Class: TLS::DigitallySigned
- Inherits:
-
Object
- Object
- TLS::DigitallySigned
- Defined in:
- lib/tls/digitally_signed.rb
Overview
Create a DigitallySigned struct, as defined by RFC5246 s4.7, and adapted
for the CertificateTransparency system (that is, ECDSA using the NIST
P-256 curve is the only signature algorithm supported, and SHA-256 is the
only hash algorithm supported).
Instance Attribute Summary collapse
-
#content ⇒ Object
Returns the value of attribute content.
-
#hash_algorithm ⇒ Object
Returns the value of attribute hash_algorithm.
-
#key ⇒ Object
Returns the value of attribute key.
-
#signature ⇒ Object
Returns the value of attribute signature.
-
#signature_algorithm ⇒ Object
Returns the value of attribute signature_algorithm.
Class Method Summary collapse
-
.from_blob(blob) ⇒ Object
Create a new
DigitallySignedstruct.
Instance Method Summary collapse
-
#to_blob ⇒ Object
Return a binary string which represents a
DigitallySignedstruct of the content passed in. -
#valid? ⇒ Boolean
Verify whether or not the
signaturestruct given is a valid signature for the key/content/blob combination provided to the constructor.
Instance Attribute Details
#content ⇒ Object
Returns the value of attribute content.
61 62 63 |
# File 'lib/tls/digitally_signed.rb', line 61 def content @content end |
#hash_algorithm ⇒ Object
Returns the value of attribute hash_algorithm.
61 62 63 |
# File 'lib/tls/digitally_signed.rb', line 61 def hash_algorithm @hash_algorithm end |
#key ⇒ Object
Returns the value of attribute key.
62 63 64 |
# File 'lib/tls/digitally_signed.rb', line 62 def key @key end |
#signature ⇒ Object
Returns the value of attribute signature.
61 62 63 |
# File 'lib/tls/digitally_signed.rb', line 61 def signature @signature end |
#signature_algorithm ⇒ Object
Returns the value of attribute signature_algorithm.
61 62 63 |
# File 'lib/tls/digitally_signed.rb', line 61 def signature_algorithm @signature_algorithm end |
Class Method Details
.from_blob(blob) ⇒ Object
Create a new DigitallySigned struct.
Takes a number of named options:
:key-- (required) An instance ofOpenSSL::PKey::PKey. If you pass in:blobas well, then this can be either a public key or a private key (because you only need a public key for validating a signature), but if you only pass in:content, you must provide a private key here.
This key must be generated with the NIST P-256 curve (known to
OpenSSL as prime256v1), or be an RSA key of at least 2048 bits, in
order to be compliant with the CT spec. However, we can't validate
some of those criteria, so it's up to you to make sure you do it
right.
:content-- (required) The content to sign, or verify the signature of. This can be any string.:blob-- An existing encodedDigitallySignedstruct you'd like to have decoded and verified against:contentwith:key.
Raises an ArgumentError if you try to pass in anything that doesn't
meet the rather stringent requirements.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/tls/digitally_signed.rb', line 38 def self.from_blob(blob) hash_algorithm, signature_algorithm, sig_blob = blob.unpack("CCa*") unless ::TLS::SignatureAlgorithm.values.include?(signature_algorithm) raise ArgumentError, "invalid signature type specified (#{signature_algorithm})" end if hash_algorithm != ::TLS::HashAlgorithm[:sha256] raise ArgumentError, "Hash algorithm specified in blob is not SHA256" end sig, rest = ::TLS::Opaque.from_blob(sig_blob, 2**16-1) signature = sig.value TLS::DigitallySigned.new.tap do |ds| ds.hash_algorithm = hash_algorithm ds.signature_algorithm = signature_algorithm ds.signature = signature end end |
Instance Method Details
#to_blob ⇒ Object
Return a binary string which represents a DigitallySigned struct of
the content passed in.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/tls/digitally_signed.rb', line 89 def to_blob if @key.nil? raise RuntimeError, "No key has been supplied" end begin @signature ||= @key.sign(OpenSSL::Digest::SHA256.new, @content) rescue ArgumentError raise RuntimeError, "Must have a private key in order to make a signature" end [ @hash_algorithm, @signature_algorithm, @signature.length, @signature ].pack("CCna*").force_encoding("BINARY") end |
#valid? ⇒ Boolean
Verify whether or not the signature struct given is a valid signature
for the key/content/blob combination provided to the constructor.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/tls/digitally_signed.rb', line 112 def valid? if @key.nil? raise RuntimeError, "No key has been specified" end if @signature.nil? raise RuntimeError, "No signature is available yet" end if @content.nil? raise RuntimeError, "No content has been specified yet" end @key.verify(OpenSSL::Digest::SHA256.new, @signature, @content) end |