aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngela Anderton Andin <ingela@erlang.org>2013-04-24 10:51:51 +0200
committerIngela Anderton Andin <ingela@erlang.org>2013-05-08 10:39:20 +0200
commitabfa5825923caad09691313f39e843b70aee8f19 (patch)
tree5a9fa7daba08ee9a114240f25505a31b40a7d20f
parent8537e256d5bb250f6e798d521deef16907a4e526 (diff)
downloadotp-abfa5825923caad09691313f39e843b70aee8f19.tar.gz
otp-abfa5825923caad09691313f39e843b70aee8f19.tar.bz2
otp-abfa5825923caad09691313f39e843b70aee8f19.zip
ssl & public_key: API refinement
Change API so public_key:generate_key/compute_key are only called with "public_key arguments" otherwhise crypto functions can be called explicitly.
-rw-r--r--lib/public_key/src/public_key.erl55
-rw-r--r--lib/ssl/src/ssl_connection.erl37
2 files changed, 35 insertions, 57 deletions
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index ee5c5e8552..df4f38f507 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -326,38 +326,19 @@ encrypt_private(PlainText,
crypto:rsa_private_encrypt(PlainText, format_rsa_private_key(Key), Padding).
%%--------------------------------------------------------------------
--spec generate_key(#'ECPrivateKey'{} | {curve, Name ::atom()} | #'DHParameter'{}) -> {'ECKey', term()} | {binary(), binary()}.
-%% Description: Generates new key(s)
+-spec generate_key(#'DHParameter'{} | {namedCurve, Name ::atom()} | #'OTPECParameters'{}) -> {Public::binary(), Private::binary()}.
+%% Description: Generates a new keypair
%%--------------------------------------------------------------------
-generate_key({curve, Name}) ->
- Term = crypto:ecdh_generate_key(Name),
- ec_key(Term, Name);
-
generate_key(#'DHParameter'{prime = P, base = G}) ->
crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]);
-
-generate_key({dh, Prime, Base}) when is_binary(Prime), is_binary(Base) ->
- %% TODO: Is mpint could be normal binary!
- crypto:dh_generate_key([Prime, Base]);
-
-generate_key({srp, Version, Generator, Prime}) when is_binary(Generator), is_binary(Prime) ->
- crypto:srp_generate_key(Generator, Prime, Version);
-
-generate_key({srp, Version, Verifier, Generator, Prime}) when is_binary(Verifier), is_binary(Generator), is_binary(Prime) ->
- crypto:srp_generate_key(Verifier, Generator, Prime, Version);
-
-generate_key(Params) ->
- Curve = ec_curve_spec(Params),
- Term = crypto:ecdh_generate_key(Curve),
- ec_key(Term, Params).
+generate_key({namedCurve, _} = Params) ->
+ ec_generate_key(Params);
+generate_key(#'OTPECParameters'{} = Params) ->
+ ec_generate_key(Params).
%%--------------------------------------------------------------------
--spec compute_key(#'ECPoint'{}, #'ECPrivateKey'{} | crypto:ecdh_key()) -> binary().
--spec compute_key(OthersKey ::binary(), MyKey::binary() | {binary(), binary()},
- {dh, binary(), binary()} |
- {srp,'3'|'6'| '6a' , binary(), binary()} |
- {srp, string(), string(), binary(), '3'|'6'| '6a', binary(), binary()})
- -> binary().
+-spec compute_key(#'ECPoint'{} , #'ECPrivateKey'{}) -> binary().
+-spec compute_key(OthersKey ::binary(), MyKey::binary(), #'DHParameter'{}) -> binary().
%% Description: Compute shared secret
%%--------------------------------------------------------------------
compute_key(PubKey, #'ECPrivateKey'{} = PrivateKey) ->
@@ -366,19 +347,8 @@ compute_key(PubKey, #'ECPrivateKey'{} = PrivateKey) ->
compute_key(#'ECPoint'{point = Point}, ECDHKeys) ->
crypto:ecdh_compute_key(Point, ECDHKeys).
-compute_key(OthersKey, MyKey, {dh, Prime, Base}) when is_binary(OthersKey),
- is_binary(MyKey),
- is_binary(Prime),
- is_binary(Base) ->
- %% TODO: Is mpint could be binary!
- crypto:dh_compute_key(OthersKey, MyKey, [Prime, Base]);
-
-compute_key(ClientPub, {ServerPub, ServerPriv}, {srp, Version, Verifier, Prime}) ->
- crypto:srp_compute_key(Verifier, Prime, ClientPub, ServerPub, ServerPriv, Version);
-
-compute_key(ServerPub, {ClientPub, ClientPriv}, {srp, Username, Password, Salt, Version, Prime, Generator}) ->
- DerivedKey = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- crypto:srp_compute_key(DerivedKey, Prime, Generator, ClientPub, ClientPriv, ServerPub, Version).
+compute_key(PubKey, PrivKey, #'DHParameter'{prime = P, base = G}) ->
+ crypto:dh_compute_key(PubKey, PrivKey, [crypto:mpint(P), crypto:mpint(G)]).
%%--------------------------------------------------------------------
-spec pkix_sign_types(SignatureAlg::oid()) ->
@@ -898,6 +868,11 @@ format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E,
is_integer(D) ->
[E, N, D].
+ec_generate_key(Params) ->
+ Curve = ec_curve_spec(Params),
+ Term = crypto:ecdh_generate_key(Curve),
+ ec_key(Term, Params).
+
format_ecdh_key(#'ECPrivateKey'{privateKey = PrivKey,
parameters = Param,
publicKey = _}) ->
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 2a32bdf066..750604c8b6 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -673,9 +673,9 @@ certify_client_key_exchange(#encrypted_premaster_secret{premaster_secret= EncPMS
certify_client_key_exchange(#client_diffie_hellman_public{dh_public = ClientPublicDhKey},
#state{negotiated_version = Version,
diffie_hellman_params = #'DHParameter'{prime = P,
- base = G},
+ base = G} = Params,
diffie_hellman_keys = {_, ServerDhPrivateKey}} = State0) ->
- case dh_master_secret(crypto:mpint(P), crypto:mpint(G), ClientPublicDhKey, ServerDhPrivateKey, State0) of
+ case dh_master_secret(Params, ClientPublicDhKey, ServerDhPrivateKey, State0) of
#state{} = State1 ->
{Record, State} = next_record(State1),
next_state(certify, cipher, Record, State);
@@ -2084,17 +2084,20 @@ master_from_premaster_secret(PremasterSecret,
Alert
end.
+dh_master_secret(#'DHParameter'{} = Params, OtherPublicDhKey, MyPrivateKey, State) ->
+ PremasterSecret =
+ public_key:compute_key(mpint_binary(OtherPublicDhKey), MyPrivateKey, Params),
+ master_from_premaster_secret(PremasterSecret, State).
+
dh_master_secret(Prime, Base, PublicDhKey, undefined, State) ->
PMpint = mpint_binary(Prime),
GMpint = mpint_binary(Base),
- Keys = {_, PrivateDhKey} =
- public_key:generate_key({dh, PMpint,GMpint}),
+ Keys = {_, PrivateDhKey} = crypto:dh_generate_key([PMpint, GMpint]),
dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey, State#state{diffie_hellman_keys = Keys});
dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey, State) ->
PremasterSecret =
- public_key:compute_key(mpint_binary(PublicDhKey), PrivateDhKey,
- {dh, PMpint, GMpint}),
+ crypto:dh_compute_key(mpint_binary(PublicDhKey), PrivateDhKey, [PMpint, GMpint]),
master_from_premaster_secret(PremasterSecret, State).
ec_dh_master_secret(ECDHKeys, ECPoint, State) ->
@@ -2125,7 +2128,7 @@ dhe_psk_master_secret(PSKIdentity, Prime, Base, PublicDhKey, undefined, State) -
PMpint = mpint_binary(Prime),
GMpint = mpint_binary(Base),
Keys = {_, PrivateDhKey} =
- public_key:generate_key({dh, PMpint, GMpint}),
+ crypto:dh_generate_key([PMpint, GMpint]),
dhe_psk_master_secret(PSKIdentity, PMpint, GMpint, PublicDhKey, PrivateDhKey,
State#state{diffie_hellman_keys = Keys});
@@ -2134,8 +2137,8 @@ dhe_psk_master_secret(PSKIdentity, PMpint, GMpint, PublicDhKey, PrivateDhKey,
case handle_psk_identity(PSKIdentity, SslOpts#ssl_options.user_lookup_fun) of
{ok, PSK} when is_binary(PSK) ->
DHSecret =
- public_key:compute_key(mpint_binary(PublicDhKey), PrivateDhKey,
- {dh, PMpint, GMpint}),
+ crypto:dh_compute_key(mpint_binary(PublicDhKey), PrivateDhKey,
+ [PMpint, GMpint]),
DHLen = erlang:byte_size(DHSecret),
Len = erlang:byte_size(PSK),
PremasterSecret = <<?UINT16(DHLen), DHSecret/binary, ?UINT16(Len), PSK/binary>>,
@@ -2164,7 +2167,7 @@ generate_srp_server_keys(_SrpParams, 10) ->
generate_srp_server_keys(SrpParams =
#srp_user{generator = Generator, prime = Prime,
verifier = Verifier}, N) ->
- case public_key:generate_key({srp, '6a', Verifier, Generator, Prime}) of
+ case crypto:srp_generate_key(Verifier, Generator, Prime, '6a') of
error ->
generate_srp_server_keys(SrpParams, N+1);
Keys ->
@@ -2175,7 +2178,7 @@ generate_srp_client_keys(_Generator, _Prime, 10) ->
?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER);
generate_srp_client_keys(Generator, Prime, N) ->
- case public_key:generate_key({srp, '6a', Generator, Prime}) of
+ case crypto:srp_generate_key(Generator, Prime, '6a') of
error ->
generate_srp_client_keys(Generator, Prime, N+1);
Keys ->
@@ -2196,8 +2199,8 @@ handle_srp_identity(Username, {Fun, UserState}) ->
throw(?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER))
end.
-server_srp_master_secret(Verifier, Prime, ClientPub, State = #state{srp_keys = ServerKey}) ->
- case public_key:compute_key(ClientPub, ServerKey, {srp, '6a', Verifier, Prime}) of
+server_srp_master_secret(Verifier, Prime, ClientPub, State = #state{srp_keys = {ServerPub, ServerPriv}}) ->
+ case crypto:srp_compute_key(Verifier, Prime, ClientPub, ServerPub, ServerPriv, '6a') of
error ->
?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER);
PremasterSecret ->
@@ -2210,13 +2213,13 @@ client_srp_master_secret(Generator, Prime, Salt, ServerPub, undefined, State) ->
Keys = generate_srp_client_keys(Generator, Prime, 0),
client_srp_master_secret(Generator, Prime, Salt, ServerPub, Keys, State#state{srp_keys = Keys});
-client_srp_master_secret(Generator, Prime, Salt, ServerPub, ClientKeys,
- #state{ssl_options = SslOpts} = State) ->
+client_srp_master_secret(Generator, Prime, Salt, ServerPub, {ClientPub, ClientPriv},
+ #state{ssl_options = SslOpts} = State) ->
case ssl_srp_primes:check_srp_params(Generator, Prime) of
ok ->
{Username, Password} = SslOpts#ssl_options.srp_identity,
- case public_key:compute_key(ServerPub, ClientKeys, {srp, Username, Password, Salt,
- '6a', Prime, Generator}) of
+ DerivedKey = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
+ case crypto:srp_compute_key(DerivedKey, Prime, Generator, ClientPub, ClientPriv, ServerPub, '6a') of
error ->
?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER);
PremasterSecret ->