aboutsummaryrefslogtreecommitdiffstats
path: root/lib/public_key/src
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2013-05-28 11:38:20 +0200
committerIngela Anderton Andin <[email protected]>2013-05-28 11:38:20 +0200
commite910933e572a84f145184000438097c4f2a531d7 (patch)
tree556607170e64156d193fc08a72c8a29a4ee1e75f /lib/public_key/src
parent1b5d887a79f31031caf3fc9f0b282b2d1ce71ce9 (diff)
parent7f5fa1b06671d31476e0fc0f28b878a6b5059b1b (diff)
downloadotp-e910933e572a84f145184000438097c4f2a531d7.tar.gz
otp-e910933e572a84f145184000438097c4f2a531d7.tar.bz2
otp-e910933e572a84f145184000438097c4f2a531d7.zip
Merge remote-tracking branch 'upstream/maint'
Conflicts: bootstrap/lib/stdlib/ebin/beam_lib.beam lib/public_key/test/erl_make_certs.erl
Diffstat (limited to 'lib/public_key/src')
-rw-r--r--lib/public_key/src/pubkey_pbe.erl64
-rw-r--r--lib/public_key/src/pubkey_ssh.erl43
-rw-r--r--lib/public_key/src/public_key.erl16
3 files changed, 72 insertions, 51 deletions
diff --git a/lib/public_key/src/pubkey_pbe.erl b/lib/public_key/src/pubkey_pbe.erl
index 43f6c42f10..6f0be53db9 100644
--- a/lib/public_key/src/pubkey_pbe.erl
+++ b/lib/public_key/src/pubkey_pbe.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,7 +23,7 @@
-include("public_key.hrl").
-export([encode/4, decode/4, decrypt_parameters/1]).
--export([pbdkdf1/4, pbdkdf2/6]).
+-export([pbdkdf1/4, pbdkdf2/7]).
-define(DEFAULT_SHA_MAC_KEYLEN, 20).
-define(ASN1_OCTET_STR_TAG, 4).
@@ -40,16 +40,16 @@
%%--------------------------------------------------------------------
encode(Data, Password, "DES-CBC" = Cipher, KeyDevParams) ->
{Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams),
- crypto:des_cbc_encrypt(Key, IV, Data);
+ crypto:block_encrypt(des_cbc, Key, IV, Data);
encode(Data, Password, "DES-EDE3-CBC" = Cipher, KeyDevParams) ->
{Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams),
<<Key1:8/binary, Key2:8/binary, Key3:8/binary>> = Key,
- crypto:des_ede3_cbc_encrypt(Key1, Key2, Key3, IV, Data);
+ crypto:block_encrypt(des3_cbc, [Key1, Key2, Key3], IV, Data);
encode(Data, Password, "RC2-CBC" = Cipher, KeyDevParams) ->
{Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams),
- crypto:rc2_cbc_encrypt(Key, IV, Data).
+ crypto:block_encrypt(rc2_cbc, Key, IV, Data).
%%--------------------------------------------------------------------
-spec decode(binary(), string(), string(), term()) -> binary().
%%
@@ -57,16 +57,16 @@ encode(Data, Password, "RC2-CBC" = Cipher, KeyDevParams) ->
%%--------------------------------------------------------------------
decode(Data, Password,"DES-CBC"= Cipher, KeyDevParams) ->
{Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams),
- crypto:des_cbc_decrypt(Key, IV, Data);
+ crypto:block_decrypt(des_cbc, Key, IV, Data);
decode(Data, Password,"DES-EDE3-CBC" = Cipher, KeyDevParams) ->
{Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams),
<<Key1:8/binary, Key2:8/binary, Key3:8/binary>> = Key,
- crypto:des_ede3_cbc_decrypt(Key1, Key2, Key3, IV, Data);
+ crypto:block_decrypt(des3_cbc, [Key1, Key2, Key3], IV, Data);
decode(Data, Password,"RC2-CBC"= Cipher, KeyDevParams) ->
{Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams),
- crypto:rc2_cbc_decrypt(Key, IV, Data).
+ crypto:block_decrypt(rc2_cbc, Key, IV, Data).
%%--------------------------------------------------------------------
-spec pbdkdf1(string(), iodata(), integer(), atom()) -> binary().
@@ -77,21 +77,21 @@ decode(Data, Password,"RC2-CBC"= Cipher, KeyDevParams) ->
pbdkdf1(_, _, 0, Acc) ->
Acc;
pbdkdf1(Password, Salt, Count, Hash) ->
- Result = crypto:Hash([Password, Salt]),
+ Result = crypto:hash(Hash, [Password, Salt]),
do_pbdkdf1(Result, Count-1, Result, Hash).
%%--------------------------------------------------------------------
--spec pbdkdf2(string(), iodata(), integer(), integer(), fun(), integer())
+-spec pbdkdf2(string(), iodata(), integer(), integer(), fun(), atom(), integer())
-> binary().
%%
%% Description: Implements password based decryption key derive function 2.
%% Exported mainly for testing purposes.
%%--------------------------------------------------------------------
-pbdkdf2(Password, Salt, Count, DerivedKeyLen, Prf, PrfOutputLen)->
+pbdkdf2(Password, Salt, Count, DerivedKeyLen, Prf, PrfHash, PrfOutputLen)->
NumBlocks = ceiling(DerivedKeyLen / PrfOutputLen),
NumLastBlockOctets = DerivedKeyLen - (NumBlocks - 1) * PrfOutputLen ,
blocks(NumBlocks, NumLastBlockOctets, 1, Password, Salt,
- Count, Prf, PrfOutputLen, <<>>).
+ Count, Prf, PrfHash, PrfOutputLen, <<>>).
%%--------------------------------------------------------------------
-spec decrypt_parameters(#'EncryptedPrivateKeyInfo_encryptionAlgorithm'{}) ->
{Cipher::string(), #'PBES2-params'{}}.
@@ -106,10 +106,10 @@ decrypt_parameters(#'EncryptedPrivateKeyInfo_encryptionAlgorithm'{
%%% Internal functions
%%--------------------------------------------------------------------
password_to_key_and_iv(Password, _, #'PBES2-params'{} = Params) ->
- {Salt, ItrCount, KeyLen, PseudoRandomFunction, PseudoOtputLen, IV} =
+ {Salt, ItrCount, KeyLen, PseudoRandomFunction, PseudoHash, PseudoOtputLen, IV} =
key_derivation_params(Params),
<<Key:KeyLen/binary, _/binary>> =
- pbdkdf2(Password, Salt, ItrCount, KeyLen, PseudoRandomFunction, PseudoOtputLen),
+ pbdkdf2(Password, Salt, ItrCount, KeyLen, PseudoRandomFunction, PseudoHash, PseudoOtputLen),
{Key, IV};
password_to_key_and_iv(Password, Cipher, Salt) ->
KeyLen = derived_key_length(Cipher, undefined),
@@ -122,13 +122,13 @@ password_to_key_and_iv(Password, Cipher, Salt) ->
pem_encrypt(_, _, _, 0, Acc, _) ->
Acc;
pem_encrypt(Prev, Password, Salt, Count, Acc, Hash) ->
- Result = crypto:Hash([Prev, Password, Salt]),
+ Result = crypto:hash(Hash, [Prev, Password, Salt]),
pem_encrypt(Result, Password, Salt, Count-1 , <<Acc/binary, Result/binary>>, Hash).
do_pbdkdf1(_, 0, Acc, _) ->
Acc;
do_pbdkdf1(Prev, Count, Acc, Hash) ->
- Result = crypto:Hash(Prev),
+ Result = crypto:hash(Hash, Prev),
do_pbdkdf1(Result, Count-1 , <<Result/binary, Acc/binary>>, Hash).
iv(#'PBES2-params_encryptionScheme'{algorithm = Algo,
@@ -143,23 +143,23 @@ iv(#'PBES2-params_encryptionScheme'{algorithm = ?'rc2CBC',
{ok, #'RC2-CBC-Parameter'{iv = IV}} = 'PKCS-FRAME':decode('RC2-CBC-Parameter', ASN1IV),
iolist_to_binary(IV).
-blocks(1, N, Index, Password, Salt, Count, Prf, PrfLen, Acc) ->
- <<XorSum:N/binary, _/binary>> = xor_sum(Password, Salt, Count, Index, Prf, PrfLen),
+blocks(1, N, Index, Password, Salt, Count, Prf, PrfHash, PrfLen, Acc) ->
+ <<XorSum:N/binary, _/binary>> = xor_sum(Password, Salt, Count, Index, Prf, PrfHash, PrfLen),
<<Acc/binary, XorSum/binary>>;
-blocks(NumBlocks, N, Index, Password, Salt, Count, Prf, PrfLen, Acc) ->
- XorSum = xor_sum(Password, Salt, Count, Index, Prf, PrfLen),
- blocks(NumBlocks -1, N, Index +1, Password, Salt, Count, Prf,
+blocks(NumBlocks, N, Index, Password, Salt, Count, Prf, PrfHash, PrfLen, Acc) ->
+ XorSum = xor_sum(Password, Salt, Count, Index, Prf, PrfHash, PrfLen),
+ blocks(NumBlocks -1, N, Index +1, Password, Salt, Count, Prf, PrfHash,
PrfLen, <<Acc/binary, XorSum/binary>>).
-xor_sum(Password, Salt, Count, Index, Prf, PrfLen) ->
- Result = Prf(Password, [Salt,<<Index:32/unsigned-big-integer>>], PrfLen),
- do_xor_sum(Prf, PrfLen, Result, Password, Count-1, Result).
+xor_sum(Password, Salt, Count, Index, Prf, PrfHash, PrfLen) ->
+ Result = Prf(PrfHash, Password, [Salt,<<Index:32/unsigned-big-integer>>], PrfLen),
+ do_xor_sum(Prf, PrfHash, PrfLen, Result, Password, Count-1, Result).
-do_xor_sum(_, _, _, _, 0, Acc) ->
+do_xor_sum(_, _, _, _, _, 0, Acc) ->
Acc;
-do_xor_sum(Prf, PrfLen, Prev, Password, Count, Acc)->
- Result = Prf(Password, Prev, PrfLen),
- do_xor_sum(Prf, PrfLen, Result, Password, Count-1, crypto:exor(Acc, Result)).
+do_xor_sum(Prf, PrfHash, PrfLen, Prev, Password, Count, Acc)->
+ Result = Prf(PrfHash, Password, Prev, PrfLen),
+ do_xor_sum(Prf, PrfHash, PrfLen, Result, Password, Count-1, crypto:exor(Acc, Result)).
decrypt_parameters(?'id-PBES2', DekParams) ->
{ok, Params} = 'PKCS-FRAME':decode('PBES2-params', DekParams),
@@ -174,18 +174,18 @@ key_derivation_params(#'PBES2-params'{keyDerivationFunc = KeyDerivationFunc,
keyLength = Length,
prf = Prf}} = KeyDerivationFunc,
#'PBES2-params_encryptionScheme'{algorithm = Algo} = EncScheme,
- {PseudoRandomFunction, PseudoOtputLen} = pseudo_random_function(Prf),
+ {PseudoRandomFunction, PseudoHash, PseudoOtputLen} = pseudo_random_function(Prf),
KeyLen = derived_key_length(Algo, Length),
{OctetSalt, Count, KeyLen,
- PseudoRandomFunction, PseudoOtputLen, iv(EncScheme)}.
+ PseudoRandomFunction, PseudoHash, PseudoOtputLen, iv(EncScheme)}.
%% This function currently matches a tuple that ougth to be the value
%% ?'id-hmacWithSHA1, but we need some kind of ASN1-fix for this.
pseudo_random_function(#'PBKDF2-params_prf'{algorithm =
{_,_, _,'id-hmacWithSHA1'}}) ->
- {fun crypto:sha_mac/3, pseudo_output_length(?'id-hmacWithSHA1')};
+ {fun crypto:hmac/4, sha, pseudo_output_length(?'id-hmacWithSHA1')};
pseudo_random_function(#'PBKDF2-params_prf'{algorithm = ?'id-hmacWithSHA1'}) ->
- {fun crypto:sha_mac/3, pseudo_output_length(?'id-hmacWithSHA1')}.
+ {fun crypto:hmac/4, sha, pseudo_output_length(?'id-hmacWithSHA1')}.
pseudo_output_length(?'id-hmacWithSHA1') ->
?DEFAULT_SHA_MAC_KEYLEN.
diff --git a/lib/public_key/src/pubkey_ssh.erl b/lib/public_key/src/pubkey_ssh.erl
index 008ea96dd3..41280b9e14 100644
--- a/lib/public_key/src/pubkey_ssh.erl
+++ b/lib/public_key/src/pubkey_ssh.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -362,18 +362,18 @@ comma_list_encode([Option | Rest], Acc) ->
ssh2_pubkey_encode(#'RSAPublicKey'{modulus = N, publicExponent = E}) ->
TypeStr = <<"ssh-rsa">>,
StrLen = size(TypeStr),
- EBin = crypto:mpint(E),
- NBin = crypto:mpint(N),
+ EBin = mpint(E),
+ NBin = mpint(N),
<<?UINT32(StrLen), TypeStr:StrLen/binary,
EBin/binary,
NBin/binary>>;
ssh2_pubkey_encode({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
TypeStr = <<"ssh-dss">>,
StrLen = size(TypeStr),
- PBin = crypto:mpint(P),
- QBin = crypto:mpint(Q),
- GBin = crypto:mpint(G),
- YBin = crypto:mpint(Y),
+ PBin = mpint(P),
+ QBin = mpint(Q),
+ GBin = mpint(G),
+ YBin = mpint(Y),
<<?UINT32(StrLen), TypeStr:StrLen/binary,
PBin/binary,
QBin/binary,
@@ -476,3 +476,32 @@ split_n(N, Bin, Acc) ->
[Last] ->
split_n(0, <<>>, [Last | Acc])
end.
+%% large integer in a binary with 32bit length
+%% MP representaion (SSH2)
+mpint(X) when X < 0 -> mpint_neg(X);
+mpint(X) -> mpint_pos(X).
+
+mpint_neg(X) ->
+ Bin = int_to_bin_neg(X, []),
+ Sz = byte_size(Bin),
+ <<?UINT32(Sz), Bin/binary>>.
+
+mpint_pos(X) ->
+ Bin = int_to_bin_pos(X, []),
+ <<MSB,_/binary>> = Bin,
+ Sz = byte_size(Bin),
+ if MSB band 16#80 == 16#80 ->
+ <<?UINT32((Sz+1)), 0, Bin/binary>>;
+ true ->
+ <<?UINT32(Sz), Bin/binary>>
+ end.
+
+int_to_bin_pos(0,Ds=[_|_]) ->
+ list_to_binary(Ds);
+int_to_bin_pos(X,Ds) ->
+ int_to_bin_pos(X bsr 8, [(X band 255)|Ds]).
+
+int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
+ list_to_binary(Ds);
+int_to_bin_neg(X,Ds) ->
+ int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 648dba3d5a..3eea6f6ec4 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -347,7 +347,7 @@ generate_key(#'ECParameters'{} = Params) ->
compute_key(#'ECPoint'{point = Point}, #'ECPrivateKey'{privateKey = PrivKey,
parameters = Param}) ->
ECCurve = ec_curve_spec(Param),
- crypto:compute_key(ecdh, Point, list2int(PrivKey), ECCurve).
+ crypto:compute_key(ecdh, Point, list_to_binary(PrivKey), ECCurve).
compute_key(PubKey, PrivKey, #'DHParameter'{prime = P, base = G}) ->
crypto:compute_key(dh, PubKey, PrivKey, [P, G]).
@@ -402,7 +402,7 @@ sign(DigestOrPlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) ->
sign(DigestOrPlainText, DigestType, #'ECPrivateKey'{privateKey = PrivKey,
parameters = Param}) ->
ECCurve = ec_curve_spec(Param),
- crypto:sign(ecdsa, DigestType, DigestOrPlainText, [list2int(PrivKey), ECCurve]);
+ crypto:sign(ecdsa, DigestType, DigestOrPlainText, [list_to_binary(PrivKey), ECCurve]);
%% Backwards compatible
sign(Digest, none, #'DSAPrivateKey'{} = Key) ->
@@ -878,16 +878,8 @@ ec_curve_spec( #'ECParameters'{fieldID = FieldId, curve = PCurve, base = Base, o
ec_curve_spec({namedCurve, OID}) ->
pubkey_cert_records:namedCurves(OID).
-ec_key({PrivateKey, PubKey}, Params) ->
+ec_key({PubKey, PrivateKey}, Params) ->
#'ECPrivateKey'{version = 1,
- privateKey = int2list(PrivateKey),
+ privateKey = binary_to_list(PrivateKey),
parameters = Params,
publicKey = {0, PubKey}}.
-
-list2int(L) ->
- S = length(L) * 8,
- <<R:S/integer>> = erlang:iolist_to_binary(L),
- R.
-int2list(I) ->
- L = (length(integer_to_list(I, 16)) + 1) div 2,
- binary_to_list(<<I:(L*8)>>).