lib/lastpass/parser.rb in lastpass-1.5.0 vs lib/lastpass/parser.rb in lastpass-1.6.0

- old
+ new

@@ -60,34 +60,10 @@ Account.new id, name, username, password, url, group end end - # Parse PRIK chunk which contains private RSA key - def self.parse_PRIK chunk, encryption_key - decrypted = decode_aes256 "cbc", - encryption_key[0, 16], - decode_hex(chunk.payload), - encryption_key - - /^LastPassPrivateKey<(?<hex_key>.*)>LastPassPrivateKey$/ =~ decrypted - asn1_encoded_all = OpenSSL::ASN1.decode decode_hex hex_key - asn1_encoded_key = OpenSSL::ASN1.decode asn1_encoded_all.value[2].value - - rsa_key = OpenSSL::PKey::RSA.new - rsa_key.n = asn1_encoded_key.value[1].value - rsa_key.e = asn1_encoded_key.value[2].value - rsa_key.d = asn1_encoded_key.value[3].value - rsa_key.p = asn1_encoded_key.value[4].value - rsa_key.q = asn1_encoded_key.value[5].value - rsa_key.dmp1 = asn1_encoded_key.value[6].value - rsa_key.dmq1 = asn1_encoded_key.value[7].value - rsa_key.iqmp = asn1_encoded_key.value[8].value - - rsa_key - end - # TODO: Fake some data and make a test def self.parse_SHAR chunk, encryption_key, rsa_key StringIO.open chunk.payload do |io| id = read_item io encrypted_key = decode_hex read_item io @@ -110,10 +86,49 @@ # TODO: Return an object, not a hash {id: id, name: name, encryption_key: key} end end + # Parse and decrypt the encrypted private RSA key + def self.parse_private_key encrypted_private_key, encryption_key + decrypted = decode_aes256 "cbc", + encryption_key[0, 16], + decode_hex(encrypted_private_key), + encryption_key + + /^LastPassPrivateKey<(?<hex_key>.*)>LastPassPrivateKey$/ =~ decrypted + asn1_encoded_all = OpenSSL::ASN1.decode decode_hex hex_key + asn1_encoded_key = OpenSSL::ASN1.decode asn1_encoded_all.value[2].value + + rsa_key = OpenSSL::PKey::RSA.new + n = asn1_encoded_key.value[1].value + e = asn1_encoded_key.value[2].value + d = asn1_encoded_key.value[3].value + p = asn1_encoded_key.value[4].value + q = asn1_encoded_key.value[5].value + dmp1 = asn1_encoded_key.value[6].value + dmq1 = asn1_encoded_key.value[7].value + iqmp = asn1_encoded_key.value[8].value + + if rsa_key.respond_to? :set_key + rsa_key.set_key n, e, d + rsa_key.set_factors p, q + rsa_key.set_crt_params dmp1, dmq1, iqmp + else + rsa_key.n = n + rsa_key.e = e + rsa_key.d = d + rsa_key.p = p + rsa_key.q = q + rsa_key.dmp1 = dmp1 + rsa_key.dmq1 = dmq1 + rsa_key.iqmp = iqmp + end + + rsa_key + end + def self.parse_secure_note_server notes info = {} notes.split("\n").each do |i| key, value = i.split ":", 2 @@ -273,10 +288,10 @@ # Decrypt AES-256 bytes. # Allowed ciphers are: :ecb, :cbc. # If for :ecb iv is not used and should be set to "". def self.decode_aes256 cipher, iv, data, encryption_key - aes = OpenSSL::Cipher::Cipher.new "aes-256-#{cipher}" + aes = OpenSSL::Cipher.new "aes-256-#{cipher}" aes.decrypt aes.key = encryption_key aes.iv = iv aes.update(data) + aes.final end