class SSHData::PublicKey::DSA
Attributes
Public Class Methods
SSHData::PublicKey::Base::new
# File lib/ssh_data/public_key/dsa.rb, line 52 def initialize(algo:, p:, q:, g:, y:) unless algo == ALGO_DSA raise DecodeError, "bad algorithm: #{algo.inspect}" end @p = p @q = q @g = g @y = y @openssl = OpenSSL::PKey::DSA.new(asn1.to_der) super(algo: algo) end
Convert an SSH encoded DSA
signature to DER encoding for verification with OpenSSL.
sig - A binary String signature from an SSH packet.
Returns a binary String signature, as expected by OpenSSL.
# File lib/ssh_data/public_key/dsa.rb, line 12 def self.openssl_signature(sig) if sig.bytesize != 40 raise DecodeError, "bad DSA signature size" end r = OpenSSL::BN.new(sig.byteslice(0, 20), 2) s = OpenSSL::BN.new(sig.byteslice(20, 20), 2) OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::Integer.new(r), OpenSSL::ASN1::Integer.new(s) ]).to_der end
Convert an DER encoded DSA
signature, as generated by OpenSSL to SSH encoding.
sig - A binary String signature, as generated by OpenSSL.
Returns a binary String signature, as found in an SSH packet.
# File lib/ssh_data/public_key/dsa.rb, line 32 def self.ssh_signature(sig) a1 = OpenSSL::ASN1.decode(sig) if a1.tag_class != :UNIVERSAL || a1.tag != OpenSSL::ASN1::SEQUENCE || a1.value.count != 2 raise DecodeError, "bad asn1 signature" end r, s = a1.value if r.tag_class != :UNIVERSAL || r.tag != OpenSSL::ASN1::INTEGER || s.tag_class != :UNIVERSAL || s.tag != OpenSSL::ASN1::INTEGER raise DecodeError, "bad asn1 signature" end # left pad big endian representations to 20 bytes and concatenate [ "\x00" * (20 - r.value.num_bytes), r.value.to_s(2), "\x00" * (20 - s.value.num_bytes), s.value.to_s(2) ].join end
Public Instance Methods
Is this public key equal to another public key?
other - Another SSHData::PublicKey::Base
instance to compare with.
Returns boolean.
SSHData::PublicKey::Base#==
# File lib/ssh_data/public_key/dsa.rb, line 101 def ==(other) super && other.p == p && other.q == q && other.g == g && other.y == y end
RFC4253 binary encoding of the public key.
Returns a binary String.
# File lib/ssh_data/public_key/dsa.rb, line 86 def rfc4253 Encoding.encode_fields( [:string, algo], [:mpint, p], [:mpint, q], [:mpint, g], [:mpint, y], ) end
Verify an SSH signature.
signed_data - The String message that the signature was calculated over. signature - The binarty String signature with SSH encoding.
Returns boolean.
# File lib/ssh_data/public_key/dsa.rb, line 73 def verify(signed_data, signature) sig_algo, ssh_sig, _ = Encoding.decode_signature(signature) if sig_algo != ALGO_DSA raise DecodeError, "bad signature algorithm: #{sig_algo.inspect}" end openssl_sig = self.class.openssl_signature(ssh_sig) openssl.verify(OpenSSL::Digest::SHA1.new, openssl_sig, signed_data) end
Private Instance Methods
# File lib/ssh_data/public_key/dsa.rb, line 107 def asn1 OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ObjectId.new("DSA"), OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::Integer.new(p), OpenSSL::ASN1::Integer.new(q), OpenSSL::ASN1::Integer.new(g), ]), ]), OpenSSL::ASN1::BitString.new(OpenSSL::ASN1::Integer.new(y).to_der), ]) end