Class: CertificateTransparency::TimestampedEntry
- Inherits:
-
Object
- Object
- CertificateTransparency::TimestampedEntry
- Defined in:
- lib/certificate-transparency/timestamped_entry.rb
Overview
An RFC6962 TimestampedEntry structure
Use TimestampedEntry.from_blob if you have an encoded TE you wish to decode, or create a
new instance, set the various parameters, and use #to_blob to give you
an encoded structure you can put over the wire. The various elements of
the TE struct are available via accessors.
Instance Attribute Summary collapse
-
#entry_type ⇒ Symbol
readonly
The type of entry we've got here.
-
#precert_entry ⇒ CertificateTransparency::PreCert
An instance of ::CertificateTransparency::PreCert if
entry_type == :precert_entry, or nil otherwise. -
#timestamp ⇒ Time
An instance of Time representing the timestamp of this entry.
-
#x509_entry ⇒ OpenSSL::X509::Certificate
An OpenSSL::X509::Certificate instance, if
entry_type == :x509_entry, or nil otherwise.
Class Method Summary collapse
-
.from_blob(blob) ⇒ CertificateTransparency::TimestampedEntry
Create a new TimestampedEntry by decoding a binary blob.
Instance Method Summary collapse
-
#signed_entry ⇒ OpenSSL::X509::Certificate, CertificateTransparency::PreCert
Gives you whichever of
#x509_entryor#precert_entryis not nil, ornilif both of them arenil. -
#to_blob ⇒ String
Encode this TimestampedEntry into a binary blob.
Instance Attribute Details
#entry_type ⇒ Symbol (readonly)
The type of entry we've got here. Is a symbol, either :x509_entry or :precert_entry.
20 21 22 |
# File 'lib/certificate-transparency/timestamped_entry.rb', line 20 def entry_type @entry_type end |
#precert_entry ⇒ CertificateTransparency::PreCert
An instance of ::CertificateTransparency::PreCert if entry_type ==
:precert_entry, or nil otherwise.
34 35 36 |
# File 'lib/certificate-transparency/timestamped_entry.rb', line 34 def precert_entry @precert_entry end |
#timestamp ⇒ Time
An instance of Time representing the timestamp of this entry
13 14 15 |
# File 'lib/certificate-transparency/timestamped_entry.rb', line 13 def end |
#x509_entry ⇒ OpenSSL::X509::Certificate
An OpenSSL::X509::Certificate instance, if entry_type == :x509_entry,
or nil otherwise.
27 28 29 |
# File 'lib/certificate-transparency/timestamped_entry.rb', line 27 def x509_entry @x509_entry end |
Class Method Details
.from_blob(blob) ⇒ CertificateTransparency::TimestampedEntry
Create a new CertificateTransparency::TimestampedEntry by decoding a binary blob.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/certificate-transparency/timestamped_entry.rb', line 45 def self.from_blob(blob) ts, entry_type, rest = blob.unpack("Q>na*") new.tap do |te| te. = Time.ms(ts) case CertificateTransparency::LogEntryType.invert[entry_type] when :x509_entry cert_data, rest = TLS::Opaque.from_blob(rest, 2**24-1) te.x509_entry = OpenSSL::X509::Certificate.new(cert_data.value) when :precert_entry # Holy fuck, can I have ASN1 back, please? I can't just pass # the PreCert part of the blob into CT::PreCert.new, because I # can't parse the PreCert part out of the blob without digging # *into* the PreCert part, because the only information on how # long TBSCertificate is is contained *IN THE PRECERT!* # # I'm surprised there aren't a lot more bugs in TLS # implementations, if this is how they lay out their data # structures. ikh, tbsc_len_hi, tbsc_len_lo, rest = rest.unpack("a32nCa*") tbsc_len = tbsc_len_hi * 256 + tbsc_len_lo tbsc, rest = rest.unpack("a#{tbsc_len}a*") te.precert_entry = ::CertificateTransparency::PreCert.new.tap do |ctpc| ctpc.issuer_key_hash = ikh ctpc.tbs_certificate = tbsc end else raise ArgumentError, "Unknown LogEntryType: #{entry_type} (corrupt TimestampedEntry?)" end exts, rest = TLS::Opaque.from_blob(rest, 2**16-1) unless exts.value == "" raise ArgumentError, "Non-empty extensions found (#{exts.value.inspect})" end unless rest == "" raise ArgumentError, "Corrupted blob (garbage data after extensions)" end end end |
Instance Method Details
#signed_entry ⇒ OpenSSL::X509::Certificate, CertificateTransparency::PreCert
Gives you whichever of #x509_entry or #precert_entry is
not nil, or nil if both of them are nil.
95 96 97 |
# File 'lib/certificate-transparency/timestamped_entry.rb', line 95 def signed_entry @x509_entry or @precert_entry end |
#to_blob ⇒ String
Encode this CertificateTransparency::TimestampedEntry into a binary blob.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/certificate-transparency/timestamped_entry.rb', line 151 def to_blob signed_entry = if @x509_entry TLS::Opaque.new(@x509_entry.to_der, 2**24-1).to_blob elsif @precert_entry @precert_entry.to_blob else raise RuntimeError, "You must call #precert_entry= or #x509_entry= before calling #to_blob" end [.ms, CertificateTransparency::LogEntryType[entry_type], signed_entry, 0 ].pack("Q>na*n") end |