Module: Tem::Cert
- Defined in:
- lib/tem/_cert.rb
Overview
@author: Jorge de la Garza (MIT ‘08), [email protected] The Cert module contains methods for digesting a X.509 certificate into a tag for the TEM and to methods to reconstruct the certificate from the tag. Methods to create some sample certificates are also included for convenience.
Class Method Summary collapse
- .create_cert_from_tag(tag, issuer_cert) ⇒ Object
- .create_issuer_cert(key) ⇒ Object
- .create_subject_cert(subject_key, issuer_key, issuer_cert) ⇒ Object
-
.create_tag_from_cert(cert) ⇒ Object
The tag is 527 bytes long.
-
.extract_key(tag) ⇒ Object
returns a OpenSSL::PKey::RSA public key.
-
.extract_not_after(tag) ⇒ Object
returns a time.
-
.extract_not_before(tag) ⇒ Object
returns a Time.
-
.extract_serial_num(tag) ⇒ Object
returns a number.
-
.extract_sig_from_cert(cert) ⇒ Object
cert must be signed with sha1WithRSAEncryption algorithm TODO: how to make this method compatible with any algorithm.
Class Method Details
.create_cert_from_tag(tag, issuer_cert) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/tem/_cert.rb', line 74 def self.create_cert_from_tag(tag, issuer_cert) cert = OpenSSL::X509::Certificate.new cert.public_key = Cert.extract_key(tag) cert.serial = Cert.extract_serial_num(tag) cert_name = OpenSSL::X509::Name.new [['CN', 'TEM Device'], ['L', 'Cambridge'], ['ST', 'Massachusetts'],\ ['O', 'Trusted Execution Modules, Inc.'], ['OU', 'Certificates Division'], ['C', 'US']] cert.issuer = issuer_cert.subject cert.subject = cert_name cert.not_before = Cert.extract_not_before(tag) cert.not_after = Cert.extract_not_after(tag) return cert end |
.create_issuer_cert(key) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/tem/_cert.rb', line 13 def self.create_issuer_cert(key) issuer_cert = OpenSSL::X509::Certificate.new issuer_cert.public_key = key.public_key issuer_dist_name = OpenSSL::X509::Name.new [['CN', 'TEM Manufacturer'], ['L', 'Cambridge'], ['ST', 'Massachusetts'],\ ['O', 'Trusted Execution Modules, Inc.'], ['OU', 'Certificates Division'], ['C', 'US']] issuer_cert.issuer = issuer_dist_name issuer_cert.subject = issuer_dist_name issuer_cert.not_before = Time.now issuer_cert.not_after = Time.now + (60 * 60 * 24 * 365.25) * 10 issuer_cert.sign key, OpenSSL::Digest::SHA1.new return issuer_cert end |
.create_subject_cert(subject_key, issuer_key, issuer_cert) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/tem/_cert.rb', line 31 def self.create_subject_cert(subject_key, issuer_key, issuer_cert) subject_cert = OpenSSL::X509::Certificate.new subject_cert.public_key = subject_key.public_key subject_cert.serial = Time.now.to_i #no significance to this #, just a value for demonstration of purpose subject_dist_name = OpenSSL::X509::Name.new [['CN', 'TEM Device'], ['L', 'Cambridge'], ['ST', 'Massachusetts'],\ ['O', 'Trusted Execution Modules, Inc.'], ['OU', 'Certificates Division'], ['C', 'US']] subject_cert.issuer = issuer_cert.subject subject_cert.subject = subject_dist_name subject_cert.not_before = Time.now subject_cert.not_after = Time.now + (60 * 60 * 24 * 365.25) * 10 subject_cert.sign issuer_key, OpenSSL::Digest::SHA1.new return subject_cert end |
.create_tag_from_cert(cert) ⇒ Object
The tag is 527 bytes long. What the bytes encode is as follows:
-Serial number tag[0..3]
-Not before date tag[4..7]
-Not after date tag[8..11]
-Modulus tag[12..267]
-Public key exp tag[268..270]
-Signature tag[271..526]
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/tem/_cert.rb', line 55 def self.create_tag_from_cert(cert) tag_serial_num = Tem::CryptoAbi.to_tem_bignum(OpenSSL::BN.new(cert.serial.to_s)) while tag_serial_num.length < 4 tag_serial_num = [0] + tag_serial_num #make sure array is 4 bytes end #The dates are encoded as the number of seconds since epoch (Jan 1, 1970 00:00:00 GMT) #TODO: check that dates are exactly 4 bytes, else throw an exception tag_not_before = Tem::CryptoAbi.to_tem_bignum(OpenSSL::BN.new(cert.not_before.to_i.to_s)) tag_not_after = Tem::CryptoAbi.to_tem_bignum(OpenSSL::BN.new(cert.not_after.to_i.to_s)) tag_modulus = Tem::CryptoAbi.to_tem_bignum(OpenSSL::BN.new(cert.public_key.n.to_s)) #TODO: ensure that exponent is exactly three bytes, or come up with a safer way to encode it tag_public_exp = Tem::CryptoAbi.to_tem_bignum(OpenSSL::BN.new(cert.public_key.e.to_s)) tag = [tag_serial_num, tag_not_before, tag_not_after, tag_modulus, tag_public_exp].flatten return tag end |
.extract_key(tag) ⇒ Object
returns a OpenSSL::PKey::RSA public key
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/tem/_cert.rb', line 122 def self.extract_key(tag) mod_array = tag[12..267] mod = 0 for i in (0..mod_array.length-1) mod = mod << 8 mod += mod_array[i] end exp_array = tag[268..271] exp = 0 for i in (0..exp_array.length-1) exp = exp << 8 exp += exp_array[i] end key = OpenSSL::PKey::RSA.new key.n = mod key.e = exp return key.public_key end |
.extract_not_after(tag) ⇒ Object
returns a time
111 112 113 114 115 116 117 118 119 |
# File 'lib/tem/_cert.rb', line 111 def self.extract_not_after(tag) time_array = tag[8..11] offset_in_sec = 0 for i in (0..time_array.length-1) offset_in_sec = offset_in_sec << 8 offset_in_sec += time_array[i] end return Time.at(offset_in_sec) end |
.extract_not_before(tag) ⇒ Object
returns a Time
100 101 102 103 104 105 106 107 108 |
# File 'lib/tem/_cert.rb', line 100 def self.extract_not_before(tag) time_array = tag[4..7] offset_in_sec = 0 for i in (0..time_array.length-1) offset_in_sec = offset_in_sec << 8 offset_in_sec += time_array[i] end return Time.at(offset_in_sec) end |
.extract_serial_num(tag) ⇒ Object
returns a number
89 90 91 92 93 94 95 96 97 |
# File 'lib/tem/_cert.rb', line 89 def self.extract_serial_num(tag) serial_num_array = tag[0..3] serial_num = 0 for i in (0..serial_num_array.length-1) serial_num = serial_num << 8 serial_num += serial_num_array[i] end return serial_num end |
.extract_sig_from_cert(cert) ⇒ Object
cert must be signed with sha1WithRSAEncryption algorithm TODO: how to make this method compatible with any algorithm
146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/tem/_cert.rb', line 146 def self.extract_sig_from_cert(cert) str = 'Signature Algorithm: sha1WithRSAEncryption' text_sig = cert.to_text first_index = text_sig.index(str) text_sig = text_sig[first_index+1..-1] second_index = text_sig.index(str) sig_start_index = second_index+str.length + 1 #the 1 is for the newline character text_sig = text_sig[sig_start_index..-1] sig_array = [] text_sig.each(':') {|byte| sig_array.push(byte.delete(':').hex)} return sig_array end |