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