From ca4d1197fdf66fda5241edd645c12d2451b67ec8 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Thu, 6 Oct 2011 17:37:02 +0200 Subject: Add PKCS-8 support to public_key --- lib/public_key/src/pubkey_pem.erl | 118 +++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 47 deletions(-) (limited to 'lib/public_key/src/pubkey_pem.erl') diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl index c26815bc04..f19aab0533 100644 --- a/lib/public_key/src/pubkey_pem.erl +++ b/lib/public_key/src/pubkey_pem.erl @@ -44,7 +44,7 @@ -export([encode/1, decode/1, decipher/2, cipher/3]). %% Backwards compatibility --export([decode_key/2]). +%%-export([decode_key/2]). -define(ENCODED_LINE_LENGTH, 64). @@ -69,23 +69,27 @@ encode(PemEntries) -> encode_pem_entries(PemEntries). %%-------------------------------------------------------------------- --spec decipher({pki_asn1_type(), DerEncrypted::binary(),{Cipher :: string(), - Salt :: binary()}}, - string()) -> Der::binary(). +-spec decipher({pki_asn1_type(), DerEncrypted::binary(), term()}, + %%{Cipher :: string(), + %%Salt :: binary()}}, + string()) -> Der::binary(). %% %% Description: Deciphers a decrypted pem entry. %%-------------------------------------------------------------------- -decipher({_, DecryptDer, {Cipher,Salt}}, Password) -> - decode_key(DecryptDer, Password, Cipher, Salt). +decipher({_, DecryptDer, {Cipher, KeyDevParams}}, Password) -> + %%decode_key(DecryptDer, Password, Cipher, Salt). + pubkey_pbe:decode(DecryptDer, Password, Cipher, KeyDevParams). %%-------------------------------------------------------------------- --spec cipher(Der::binary(),{Cipher :: string(), Salt :: binary()} , +-spec cipher(Der::binary(), term(), +%%{Cipher :: string(), Hash::atom(), Salt :: binary()} , string()) -> binary(). %% %% Description: Ciphers a PEM entry %%-------------------------------------------------------------------- -cipher(Der, {Cipher,Salt}, Password)-> - encode_key(Der, Password, Cipher, Salt). +cipher(Der, {Cipher, KeyDevParams}, Password)-> + %%encode_key(Der, Password, Cipher, Salt). + pubkey_pbe:encode(Der, Password, Cipher, KeyDevParams). %%-------------------------------------------------------------------- %%% Internal functions @@ -96,7 +100,7 @@ encode_pem_entries(Entries) -> encode_pem_entry({Type, Der, not_encrypted}) -> StartStr = pem_start(Type), [StartStr, "\n", b64encode_and_split(Der), "\n", pem_end(StartStr) ,"\n\n"]; -encode_pem_entry({Type, Der, {Cipher, Salt}}) -> +encode_pem_entry({Type, Der, {Cipher, {_, Salt}}}) -> StartStr = pem_start(Type), [StartStr,"\n", pem_decrypt(),"\n", pem_decrypt_info(Cipher, Salt),"\n", b64encode_and_split(Der), "\n", pem_end(StartStr) ,"\n\n"]. @@ -122,13 +126,25 @@ decode_pem_entry(Start, [<<"Proc-Type: 4,ENCRYPTED", _/binary>>, Line | Lines]) Decoded = base64:mime_decode(Cs), [_, DekInfo0] = string:tokens(binary_to_list(Line), ": "), [Cipher, Salt] = string:tokens(DekInfo0, ","), - {Type, Decoded, {Cipher, unhex(Salt)}}; + {Type, Decoded, {Cipher, {salt, unhex(Salt)}}}; decode_pem_entry(Start, Lines) -> Type = asn1_type(Start), Cs = erlang:iolist_to_binary(Lines), Decoded = base64:mime_decode(Cs), - {Type, Decoded, not_encrypted}. + case Type of + 'EncryptedPrivateKeyInfo'-> + decode_encrypted_private_keyinfo(Decoded); + _ -> + {Type, Decoded, not_encrypted} + end. + +decode_encrypted_private_keyinfo(Der) -> + #'EncryptedPrivateKeyInfo'{encryptionAlgorithm = AlgorithmInfo, + encryptedData = Data} = public_key:der_decode('EncryptedPrivateKeyInfo', Der), + DecryptParams = pubkey_pbe:decrypt_parameters(AlgorithmInfo), + {'PrivateKeyInfo', iolist_to_binary(Data), DecryptParams}. + split_bin(Bin) -> split_bin(0, Bin). @@ -160,36 +176,36 @@ join_entry([<<"-----END ", _/binary>>| Lines], Entry) -> join_entry([Line | Lines], Entry) -> join_entry(Lines, [Line | Entry]). -decode_key(Data, Password, "DES-CBC", Salt) -> - Key = password_to_key(Password, Salt, 8), - IV = Salt, - crypto:des_cbc_decrypt(Key, IV, Data); -decode_key(Data, Password, "DES-EDE3-CBC", Salt) -> - Key = password_to_key(Password, Salt, 24), - IV = Salt, - <> = Key, - crypto:des_ede3_cbc_decrypt(Key1, Key2, Key3, IV, Data). - -encode_key(Data, Password, "DES-CBC", Salt) -> - Key = password_to_key(Password, Salt, 8), - IV = Salt, - crypto:des_cbc_encrypt(Key, IV, Data); -encode_key(Data, Password, "DES-EDE3-CBC", Salt) -> - Key = password_to_key(Password, Salt, 24), - IV = Salt, - <> = Key, - crypto:des_ede3_cbc_encrypt(Key1, Key2, Key3, IV, Data). - -password_to_key(Data, Salt, KeyLen) -> - <> = - password_to_key(<<>>, Data, Salt, KeyLen, <<>>), - Key. - -password_to_key(_, _, _, Len, Acc) when Len =< 0 -> - Acc; -password_to_key(Prev, Data, Salt, Len, Acc) -> - M = crypto:md5([Prev, Data, Salt]), - password_to_key(M, Data, Salt, Len - size(M), <>). +%% decode_key(Data, Password, "DES-CBC", Salt) -> +%% Key = password_to_key(Password, Salt, 8), +%% IV = Salt, +%% crypto:des_cbc_decrypt(Key, IV, Data); +%% decode_key(Data, Password, "DES-EDE3-CBC", Salt) -> +%% Key = password_to_key(Password, Salt, 24), +%% IV = Salt, +%% <> = Key, +%% crypto:des_ede3_cbc_decrypt(Key1, Key2, Key3, IV, Data). + +%% encode_key(Data, Password, "DES-CBC", Salt) -> +%% Key = password_to_key(Password, Salt, 8), +%% IV = Salt, +%% crypto:des_cbc_encrypt(Key, IV, Data); +%% encode_key(Data, Password, "DES-EDE3-CBC", Salt) -> +%% Key = password_to_key(Password, Salt, 24), +%% IV = Salt, +%% <> = Key, +%% crypto:des_ede3_cbc_encrypt(Key1, Key2, Key3, IV, Data). + +%% password_to_key(Data, Salt, KeyLen) -> +%% <> = +%% password_to_key(<<>>, Data, Salt, KeyLen, <<>>), +%% Key. + +%% password_to_key(_, _, _, Len, Acc) when Len =< 0 -> +%% Acc; +%% password_to_key(Prev, Data, Salt, Len, Acc) -> +%% M = crypto:md5([Prev, Data, Salt]), +%% password_to_key(M, Data, Salt, Len - size(M), <>). unhex(S) -> unhex(S, []). @@ -228,6 +244,10 @@ pem_end(<<"-----BEGIN DSA PRIVATE KEY-----">>) -> <<"-----END DSA PRIVATE KEY-----">>; pem_end(<<"-----BEGIN DH PARAMETERS-----">>) -> <<"-----END DH PARAMETERS-----">>; +pem_end(<<"-----BEGIN PRIVATE KEY-----">>) -> + <<"-----END PRIVATE KEY-----">>; +pem_end(<<"-----BEGIN ENCRYPTED PRIVATE KEY-----">>) -> + <<"-----END ENCRYPTED PRIVATE KEY-----">>; pem_end(_) -> undefined. @@ -242,7 +262,11 @@ asn1_type(<<"-----BEGIN PUBLIC KEY-----">>) -> asn1_type(<<"-----BEGIN DSA PRIVATE KEY-----">>) -> 'DSAPrivateKey'; asn1_type(<<"-----BEGIN DH PARAMETERS-----">>) -> - 'DHParameter'. + 'DHParameter'; +asn1_type(<<"-----BEGIN PRIVATE KEY-----">>) -> + 'PrivateKeyInfo'; +asn1_type(<<"-----BEGIN ENCRYPTED PRIVATE KEY-----">>) -> + 'EncryptedPrivateKeyInfo'. pem_decrypt() -> <<"Proc-Type: 4,ENCRYPTED">>. @@ -253,7 +277,7 @@ pem_decrypt_info(Cipher, Salt) -> %%-------------------------------------------------------------------- %%% Deprecated %%-------------------------------------------------------------------- -decode_key({_Type, Bin, not_encrypted}, _) -> - Bin; -decode_key({_Type, Bin, {Chipher,Salt}}, Password) -> - decode_key(Bin, Password, Chipher, Salt). +%% decode_key({_Type, Bin, not_encrypted}, _) -> +%% Bin; +%% decode_key({_Type, Bin, {Chipher,Salt}}, Password) -> +%% decode_key(Bin, Password, Chipher, Salt). -- cgit v1.2.3