diff options
Diffstat (limited to 'lib/public_key/src')
-rw-r--r-- | lib/public_key/src/Makefile | 12 | ||||
-rw-r--r-- | lib/public_key/src/pubkey_cert_records.erl | 11 | ||||
-rw-r--r-- | lib/public_key/src/public_key.erl | 128 |
3 files changed, 87 insertions, 64 deletions
diff --git a/lib/public_key/src/Makefile b/lib/public_key/src/Makefile index 062c495a65..8a72da477f 100644 --- a/lib/public_key/src/Makefile +++ b/lib/public_key/src/Makefile @@ -102,11 +102,11 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl index b86d7a1f0c..33fe940ea2 100644 --- a/lib/public_key/src/pubkey_cert_records.erl +++ b/lib/public_key/src/pubkey_cert_records.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2012. 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 @@ -57,6 +57,15 @@ transform(#'OTPTBSCertificate'{}= TBS, decode) -> transform(#'AttributeTypeAndValue'{type=Id,value=Value0} = ATAV, Func) -> {ok, Value} = case attribute_type(Id) of + 'X520countryName'when Func == decode -> + %% Workaround that some certificates break the ASN-1 spec + %% and encode countryname as utf8 + case 'OTP-PUB-KEY':Func('OTP-X520countryname', Value0) of + {ok, {utf8String, Utf8Value}} -> + {ok, unicode:characters_to_list(Utf8Value)}; + {ok, {printableString, ASCCI}} -> + {ok, ASCCI} + end; Type when is_atom(Type) -> 'OTP-PUB-KEY':Func(Type, Value0); _UnknownType -> {ok, Value0} end, diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 2e2a6cd296..d5df53e848 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2012. 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 @@ -48,8 +48,8 @@ -type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' | 'rsa_no_padding'. -type public_crypt_options() :: [{rsa_pad, rsa_padding()}]. --type rsa_digest_type() :: 'md5' | 'sha'| 'sha256' | 'sha512'. --type dss_digest_type() :: 'none' | 'sha'. +-type rsa_digest_type() :: 'md5' | 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'. +-type dss_digest_type() :: 'none' | 'sha'. %% None is for backwards compatibility -define(UINT32(X), X:32/unsigned-big-integer). -define(DER_NULL, <<5, 0>>). @@ -241,15 +241,15 @@ pkix_encode(Asn1Type, Term0, otp) when is_atom(Asn1Type) -> decrypt_private(CipherText, Key) -> decrypt_private(CipherText, Key, []). -decrypt_private(CipherText, - #'RSAPrivateKey'{modulus = N,publicExponent = E, - privateExponent = D}, - Options) when is_binary(CipherText), - is_list(Options) -> +decrypt_private(CipherText, + #'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D} = Key, + Options) + when is_binary(CipherText), + is_integer(N), is_integer(E), is_integer(D), + is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_decrypt(CipherText, - [crypto:mpint(E), crypto:mpint(N), - crypto:mpint(D)], Padding). + crypto:rsa_private_decrypt(CipherText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- -spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key()) -> @@ -307,72 +307,86 @@ encrypt_public(PlainText, #'RSAPrivateKey'{modulus=N,publicExponent=E}, encrypt_private(PlainText, Key) -> encrypt_private(PlainText, Key, []). -encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N, - publicExponent = E, - privateExponent = D}, - Options) when is_binary(PlainText), is_list(Options) -> +encrypt_private(PlainText, + #'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D} = Key, + Options) + when is_binary(PlainText), + is_integer(N), is_integer(E), is_integer(D), + is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_encrypt(PlainText, [crypto:mpint(E), - crypto:mpint(N), - crypto:mpint(D)], Padding). + crypto:rsa_private_encrypt(PlainText, format_rsa_private_key(Key), Padding). + + +format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D, + prime1 = P1, prime2 = P2, + exponent1 = E1, exponent2 = E2, + coefficient = C}) + when is_integer(P1), is_integer(P2), + is_integer(E1), is_integer(E2), is_integer(C) -> + [crypto:mpint(K) || K <- [E, N, D, P1, P2, E1, E2, C]]; + +format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D}) -> + [crypto:mpint(K) || K <- [E, N, D]]. %%-------------------------------------------------------------------- --spec sign(PlainTextOrDigest :: binary(), rsa_digest_type() | dss_digest_type(), - rsa_private_key() | +-spec sign(binary() | {digest, binary()}, rsa_digest_type() | dss_digest_type(), + rsa_private_key() | dsa_private_key()) -> Signature :: binary(). -%% %% Description: Create digital signature. %%-------------------------------------------------------------------- -sign(PlainText, DigestType, #'RSAPrivateKey'{modulus = N, publicExponent = E, - privateExponent = D}) - when is_binary(PlainText), - (DigestType == md5 orelse - DigestType == sha) -> - - crypto:rsa_sign(DigestType, sized_binary(PlainText), [crypto:mpint(E), - crypto:mpint(N), - crypto:mpint(D)]); - -sign(Digest, none, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) - when is_binary(Digest)-> - crypto:dss_sign(none, Digest, - [crypto:mpint(P), crypto:mpint(Q), +sign({digest,_}=Digest, DigestType, Key = #'RSAPrivateKey'{}) -> + crypto:rsa_sign(DigestType, Digest, format_rsa_private_key(Key)); + +sign(PlainText, DigestType, Key = #'RSAPrivateKey'{}) -> + crypto:rsa_sign(DigestType, sized_binary(PlainText), format_rsa_private_key(Key)); + +sign({digest,_}=Digest, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> + crypto:dss_sign(Digest, + [crypto:mpint(P), crypto:mpint(Q), crypto:mpint(G), crypto:mpint(X)]); - -sign(PlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) - when is_binary(PlainText) -> - crypto:dss_sign(sized_binary(PlainText), - [crypto:mpint(P), crypto:mpint(Q), - crypto:mpint(G), crypto:mpint(X)]). + +sign(PlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> + crypto:dss_sign(sized_binary(PlainText), + [crypto:mpint(P), crypto:mpint(Q), + crypto:mpint(G), crypto:mpint(X)]); + +%% Backwards compatible +sign(Digest, none, #'DSAPrivateKey'{} = Key) -> + sign({digest,Digest}, sha, Key). %%-------------------------------------------------------------------- --spec verify(PlainTextOrDigest :: binary(), rsa_digest_type() | dss_digest_type(), - Signature :: binary(), rsa_public_key() +-spec verify(binary() | {digest, binary()}, rsa_digest_type() | dss_digest_type(), + Signature :: binary(), rsa_public_key() | dsa_public_key()) -> boolean(). -%% %% Description: Verifies a digital signature. %%-------------------------------------------------------------------- -verify(PlainText, DigestType, Signature, - #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) - when is_binary (PlainText) and (DigestType == sha orelse - DigestType == sha256 orelse - DigestType == sha512 orelse - DigestType == md5) -> +verify({digest,_}=Digest, DigestType, Signature, + #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) -> + crypto:rsa_verify(DigestType, Digest, + sized_binary(Signature), + [crypto:mpint(Exp), crypto:mpint(Mod)]); + +verify(PlainText, DigestType, Signature, + #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) -> crypto:rsa_verify(DigestType, sized_binary(PlainText), sized_binary(Signature), [crypto:mpint(Exp), crypto:mpint(Mod)]); -verify(Digest, none, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) - when is_integer(Key), is_binary(Digest), is_binary(Signature) -> - crypto:dss_verify(none, - Digest, - sized_binary(Signature), +verify({digest,_}=Digest, sha, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) + when is_integer(Key), is_binary(Signature) -> + crypto:dss_verify(Digest, sized_binary(Signature), [crypto:mpint(P), crypto:mpint(Q), crypto:mpint(G), crypto:mpint(Key)]); - +%% Backwards compatibility +verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) -> + verify({digest,Digest}, sha, Signature, Key); + verify(PlainText, sha, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) - when is_integer(Key), is_binary(PlainText), is_binary(Signature) -> + when is_integer(Key), is_binary(PlainText), is_binary(Signature) -> crypto:dss_verify(sized_binary(PlainText), sized_binary(Signature), [crypto:mpint(P), crypto:mpint(Q), |