مراية لـ
https://github.com/postalserver/postal.git
تم المزامنة 2025-12-01 05:43:04 +00:00
fix: fixes postal default-dkim-record
هذا الالتزام موجود في:
@@ -1,66 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "base64"
|
|
||||||
|
|
||||||
class Signer
|
|
||||||
|
|
||||||
# Create a new Signer
|
|
||||||
#
|
|
||||||
# @param [OpenSSL::PKey::RSA] private_key The private key to use for signing
|
|
||||||
# @return [Signer]
|
|
||||||
def initialize(private_key)
|
|
||||||
@private_key = private_key
|
|
||||||
end
|
|
||||||
|
|
||||||
# Return the private key
|
|
||||||
#
|
|
||||||
# @return [OpenSSL::PKey::RSA]
|
|
||||||
attr_reader :private_key
|
|
||||||
|
|
||||||
# Return the public key for the private key
|
|
||||||
#
|
|
||||||
# @return [OpenSSL::PKey::RSA]
|
|
||||||
def public_key
|
|
||||||
@private_key.public_key
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sign the given data
|
|
||||||
#
|
|
||||||
# @param [String] data The data to sign
|
|
||||||
# @return [String] The signature
|
|
||||||
def sign(data)
|
|
||||||
private_key.sign(OpenSSL::Digest.new("SHA256"), data)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sign the given data and return a Base64-encoded signature
|
|
||||||
#
|
|
||||||
# @param [String] data The data to sign
|
|
||||||
# @return [String] The Base64-encoded signature
|
|
||||||
def sign64(data)
|
|
||||||
Base64.strict_encode64(sign(data))
|
|
||||||
end
|
|
||||||
|
|
||||||
# Return a JWK for the private key
|
|
||||||
#
|
|
||||||
# @return [JWT::JWK] The JWK
|
|
||||||
def jwk
|
|
||||||
@jwk ||= JWT::JWK.new(private_key, { use: "sig", alg: "RS256" })
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sign the given data using SHA1 (for legacy use)
|
|
||||||
#
|
|
||||||
# @param [String] data The data to sign
|
|
||||||
# @return [String] The signature
|
|
||||||
def sha1_sign(data)
|
|
||||||
private_key.sign(OpenSSL::Digest.new("SHA1"), data)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sign the given data using SHA1 (for legacy use) and return a Base64-encoded string
|
|
||||||
#
|
|
||||||
# @param [String] data The data to sign
|
|
||||||
# @return [String] The signature
|
|
||||||
def sha1_sign64(data)
|
|
||||||
Base64.strict_encode64(sha1_sign(data))
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -16,6 +16,7 @@ require_relative "error"
|
|||||||
require_relative "version"
|
require_relative "version"
|
||||||
require_relative "config_schema"
|
require_relative "config_schema"
|
||||||
require_relative "legacy_config_source"
|
require_relative "legacy_config_source"
|
||||||
|
require_relative "signer"
|
||||||
|
|
||||||
module Postal
|
module Postal
|
||||||
|
|
||||||
|
|||||||
67
lib/postal/signer.rb
Normal file
67
lib/postal/signer.rb
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "base64"
|
||||||
|
module Postal
|
||||||
|
class Signer
|
||||||
|
|
||||||
|
# Create a new Signer
|
||||||
|
#
|
||||||
|
# @param [OpenSSL::PKey::RSA] private_key The private key to use for signing
|
||||||
|
# @return [Signer]
|
||||||
|
def initialize(private_key)
|
||||||
|
@private_key = private_key
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return the private key
|
||||||
|
#
|
||||||
|
# @return [OpenSSL::PKey::RSA]
|
||||||
|
attr_reader :private_key
|
||||||
|
|
||||||
|
# Return the public key for the private key
|
||||||
|
#
|
||||||
|
# @return [OpenSSL::PKey::RSA]
|
||||||
|
def public_key
|
||||||
|
@private_key.public_key
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sign the given data
|
||||||
|
#
|
||||||
|
# @param [String] data The data to sign
|
||||||
|
# @return [String] The signature
|
||||||
|
def sign(data)
|
||||||
|
private_key.sign(OpenSSL::Digest.new("SHA256"), data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sign the given data and return a Base64-encoded signature
|
||||||
|
#
|
||||||
|
# @param [String] data The data to sign
|
||||||
|
# @return [String] The Base64-encoded signature
|
||||||
|
def sign64(data)
|
||||||
|
Base64.strict_encode64(sign(data))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return a JWK for the private key
|
||||||
|
#
|
||||||
|
# @return [JWT::JWK] The JWK
|
||||||
|
def jwk
|
||||||
|
@jwk ||= JWT::JWK.new(private_key, { use: "sig", alg: "RS256" })
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sign the given data using SHA1 (for legacy use)
|
||||||
|
#
|
||||||
|
# @param [String] data The data to sign
|
||||||
|
# @return [String] The signature
|
||||||
|
def sha1_sign(data)
|
||||||
|
private_key.sign(OpenSSL::Digest.new("SHA1"), data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sign the given data using SHA1 (for legacy use) and return a Base64-encoded string
|
||||||
|
#
|
||||||
|
# @param [String] data The data to sign
|
||||||
|
# @return [String] The signature
|
||||||
|
def sha1_sign64(data)
|
||||||
|
Base64.strict_encode64(sha1_sign(data))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
79
spec/lib/postal/signer_spec.rb
Normal file
79
spec/lib/postal/signer_spec.rb
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
module Postal
|
||||||
|
|
||||||
|
RSpec.describe Signer do
|
||||||
|
STATIC_PRIVATE_KEY = OpenSSL::PKey::RSA.new(2048) # rubocop:disable Lint/ConstantDefinitionInBlock
|
||||||
|
|
||||||
|
subject(:signer) { described_class.new(STATIC_PRIVATE_KEY) }
|
||||||
|
|
||||||
|
describe "#private_key" do
|
||||||
|
it "returns the private key" do
|
||||||
|
expect(signer.private_key).to eq(STATIC_PRIVATE_KEY)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#public_key" do
|
||||||
|
it "returns the public key" do
|
||||||
|
expect(signer.public_key.to_s).to eq(STATIC_PRIVATE_KEY.public_key.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#sign" do
|
||||||
|
it "returns a valid signature" do
|
||||||
|
data = "hello world!"
|
||||||
|
signature = signer.sign(data)
|
||||||
|
expect(signature).to be_a(String)
|
||||||
|
verification = STATIC_PRIVATE_KEY.public_key.verify(OpenSSL::Digest.new("SHA256"),
|
||||||
|
signature,
|
||||||
|
data)
|
||||||
|
expect(verification).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#sign64" do
|
||||||
|
it "returns a valid Base64-encoded signature" do
|
||||||
|
data = "hello world!"
|
||||||
|
signature = signer.sign64(data)
|
||||||
|
expect(signature).to be_a(String)
|
||||||
|
verification = STATIC_PRIVATE_KEY.public_key.verify(OpenSSL::Digest.new("SHA256"),
|
||||||
|
Base64.strict_decode64(signature),
|
||||||
|
data)
|
||||||
|
expect(verification).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#jwk" do
|
||||||
|
it "returns a valid JWK" do
|
||||||
|
jwk = signer.jwk
|
||||||
|
expect(jwk).to be_a(JWT::JWK::RSA)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#sha1_sign" do
|
||||||
|
it "returns a valid signature" do
|
||||||
|
data = "hello world!"
|
||||||
|
signature = signer.sha1_sign(data)
|
||||||
|
expect(signature).to be_a(String)
|
||||||
|
verification = STATIC_PRIVATE_KEY.public_key.verify(OpenSSL::Digest.new("SHA1"),
|
||||||
|
signature,
|
||||||
|
data)
|
||||||
|
expect(verification).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#sha1_sign64" do
|
||||||
|
it "returns a valid Base64-encoded signature" do
|
||||||
|
data = "hello world!"
|
||||||
|
signature = signer.sha1_sign64(data)
|
||||||
|
expect(signature).to be_a(String)
|
||||||
|
verification = STATIC_PRIVATE_KEY.public_key.verify(OpenSSL::Digest.new("SHA1"),
|
||||||
|
Base64.strict_decode64(signature),
|
||||||
|
data)
|
||||||
|
expect(verification).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -5,7 +5,7 @@ require "rails_helper"
|
|||||||
RSpec.describe Postal do
|
RSpec.describe Postal do
|
||||||
describe "#signer" do
|
describe "#signer" do
|
||||||
it "returns a signer with the installation's signing key" do
|
it "returns a signer with the installation's signing key" do
|
||||||
expect(Postal.signer).to be_a(Signer)
|
expect(Postal.signer).to be_a(Postal::Signer)
|
||||||
expect(Postal.signer.private_key.to_pem).to eq OpenSSL::PKey::RSA.new(File.read(Postal::Config.postal.signing_key_path)).to_pem
|
expect(Postal.signer.private_key.to_pem).to eq OpenSSL::PKey::RSA.new(File.read(Postal::Config.postal.signing_key_path)).to_pem
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "rails_helper"
|
|
||||||
|
|
||||||
RSpec.describe Signer do
|
|
||||||
STATIC_PRIVATE_KEY = OpenSSL::PKey::RSA.new(2048) # rubocop:disable Lint/ConstantDefinitionInBlock
|
|
||||||
|
|
||||||
subject(:signer) { described_class.new(STATIC_PRIVATE_KEY) }
|
|
||||||
|
|
||||||
describe "#private_key" do
|
|
||||||
it "returns the private key" do
|
|
||||||
expect(signer.private_key).to eq(STATIC_PRIVATE_KEY)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#public_key" do
|
|
||||||
it "returns the public key" do
|
|
||||||
expect(signer.public_key.to_s).to eq(STATIC_PRIVATE_KEY.public_key.to_s)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#sign" do
|
|
||||||
it "returns a valid signature" do
|
|
||||||
data = "hello world!"
|
|
||||||
signature = signer.sign(data)
|
|
||||||
expect(signature).to be_a(String)
|
|
||||||
verification = STATIC_PRIVATE_KEY.public_key.verify(OpenSSL::Digest.new("SHA256"),
|
|
||||||
signature,
|
|
||||||
data)
|
|
||||||
expect(verification).to be true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#sign64" do
|
|
||||||
it "returns a valid Base64-encoded signature" do
|
|
||||||
data = "hello world!"
|
|
||||||
signature = signer.sign64(data)
|
|
||||||
expect(signature).to be_a(String)
|
|
||||||
verification = STATIC_PRIVATE_KEY.public_key.verify(OpenSSL::Digest.new("SHA256"),
|
|
||||||
Base64.strict_decode64(signature),
|
|
||||||
data)
|
|
||||||
expect(verification).to be true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#jwk" do
|
|
||||||
it "returns a valid JWK" do
|
|
||||||
jwk = signer.jwk
|
|
||||||
expect(jwk).to be_a(JWT::JWK::RSA)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#sha1_sign" do
|
|
||||||
it "returns a valid signature" do
|
|
||||||
data = "hello world!"
|
|
||||||
signature = signer.sha1_sign(data)
|
|
||||||
expect(signature).to be_a(String)
|
|
||||||
verification = STATIC_PRIVATE_KEY.public_key.verify(OpenSSL::Digest.new("SHA1"),
|
|
||||||
signature,
|
|
||||||
data)
|
|
||||||
expect(verification).to be true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#sha1_sign64" do
|
|
||||||
it "returns a valid Base64-encoded signature" do
|
|
||||||
data = "hello world!"
|
|
||||||
signature = signer.sha1_sign64(data)
|
|
||||||
expect(signature).to be_a(String)
|
|
||||||
verification = STATIC_PRIVATE_KEY.public_key.verify(OpenSSL::Digest.new("SHA1"),
|
|
||||||
Base64.strict_decode64(signature),
|
|
||||||
data)
|
|
||||||
expect(verification).to be true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
المرجع في مشكلة جديدة
حظر مستخدم