diff options
author | Ingela Anderton Andin <[email protected]> | 2010-06-11 08:21:23 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2010-06-11 08:21:23 +0000 |
commit | 4d0e43b5e252b979d50c17592c08ae68ece5fa07 (patch) | |
tree | 179408fb7b2eb80ae402a00443c5158c9c6d9428 /lib/ssl/src | |
parent | a346eb92eb7b5bedb36768c0a63b82547919bc0b (diff) | |
download | otp-4d0e43b5e252b979d50c17592c08ae68ece5fa07.tar.gz otp-4d0e43b5e252b979d50c17592c08ae68ece5fa07.tar.bz2 otp-4d0e43b5e252b979d50c17592c08ae68ece5fa07.zip |
OTP-8695 New ssl default
Ssl has now switched default implementation and removed deprecated
certificate handling. All certificate handling is done by the public_key
application.
Diffstat (limited to 'lib/ssl/src')
-rw-r--r-- | lib/ssl/src/Makefile | 25 | ||||
-rw-r--r-- | lib/ssl/src/ssl.app.src | 9 | ||||
-rw-r--r-- | lib/ssl/src/ssl.appup.src | 2 | ||||
-rw-r--r-- | lib/ssl/src/ssl.erl | 51 | ||||
-rw-r--r-- | lib/ssl/src/ssl_base64.erl | 129 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 34 | ||||
-rw-r--r-- | lib/ssl/src/ssl_handshake.erl | 25 | ||||
-rw-r--r-- | lib/ssl/src/ssl_pem.erl | 147 | ||||
-rw-r--r-- | lib/ssl/src/ssl_pkix.erl | 307 | ||||
-rw-r--r-- | lib/ssl/src/ssl_pkix.hrl | 81 | ||||
-rw-r--r-- | lib/ssl/src/ssl_ssl3.erl | 2 |
11 files changed, 83 insertions, 729 deletions
diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile index fabf8a4e0d..7514ad2aa2 100644 --- a/lib/ssl/src/Makefile +++ b/lib/ssl/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1999-2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 1999-2010. 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 # compliance with the License. You should have received a copy of the # Erlang Public License along with this software. If not, it can be # retrieved online at http://www.erlang.org/. -# +# # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. -# +# # %CopyrightEnd% # @@ -46,9 +46,6 @@ MODULES= \ ssl_server \ ssl_sup \ ssl_prim \ - ssl_pkix \ - ssl_pem \ - ssl_base64 \ inet_ssl_dist \ ssl_certificate\ ssl_certificate_db\ @@ -71,8 +68,6 @@ INTERNAL_HRL_FILES = \ ssl_alert.hrl ssl_cipher.hrl ssl_handshake.hrl ssl_internal.hrl \ ssl_record.hrl -PUBLIC_HRL_FILES = ssl_pkix.hrl - ERL_FILES= $(MODULES:%=%.erl) TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) @@ -85,15 +80,12 @@ APP_TARGET= $(EBIN)/$(APP_FILE) APPUP_SRC= $(APPUP_FILE).src APPUP_TARGET= $(EBIN)/$(APPUP_FILE) -INCLUDE = ../include - # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- EXTRA_ERLC_FLAGS = +warn_unused_vars ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/kernel/src \ -pz $(ERL_TOP)/lib/public_key/ebin \ - -I$(INCLUDE) \ $(EXTRA_ERLC_FLAGS) -DVSN=\"$(VSN)\" @@ -101,7 +93,7 @@ ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/kernel/src \ # Targets # ---------------------------------------------------- -debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(PUBLIC_HRL_FILES) +debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) clean: rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) @@ -113,9 +105,6 @@ $(APP_TARGET): $(APP_SRC) ../vsn.mk $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk sed -e 's;%VSN%;$(VSN);' $< > $@ -$(PUBLIC_HRL_FILES): - cp -f $(PUBLIC_HRL_FILES) $(INCLUDE) - docs: # ---------------------------------------------------- @@ -126,8 +115,6 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/src $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(PUBLIC_HRL_FILES) $(RELSYSDIR)/include $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) \ $(APPUP_TARGET) $(RELSYSDIR)/ebin diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src index 2a7d451341..b9716786e6 100644 --- a/lib/ssl/src/ssl.app.src +++ b/lib/ssl/src/ssl.app.src @@ -7,10 +7,6 @@ ssl_server, ssl_broker, ssl_broker_sup, - ssl_base64, - ssl_pem, - ssl_pkix, - ssl_pkix_oid, ssl_prim, inet_ssl_dist, ssl_tls1, @@ -28,11 +24,10 @@ ssl_cipher, ssl_certificate_db, ssl_certificate, - ssl_alert, - 'OTP-PKIX' + ssl_alert ]}, {registered, [ssl_sup, ssl_server, ssl_broker_sup]}, - {applications, [kernel, stdlib]}, + {applications, [crypto, public_key, kernel, stdlib]}, {env, []}, {mod, {ssl_app, []}}]}. diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src index 52a41617bb..65f23e2f74 100644 --- a/lib/ssl/src/ssl.appup.src +++ b/lib/ssl/src/ssl.appup.src @@ -1,6 +1,7 @@ %% -*- erlang -*- {"%VSN%", [ + {"3.11.1", [{restart_application, ssl}]}, {"3.11", [{restart_application, ssl}]}, {"3.10", [{restart_application, ssl}]}, {"3.10.1", [{restart_application, ssl}]}, @@ -14,6 +15,7 @@ {"3.10.9", [{restart_application, ssl}]} ], [ + {"3.11.1", [{restart_application, ssl}]}, {"3.11", [{restart_application, ssl}]}, {"3.10", [{restart_application, ssl}]}, {"3.10.1", [{restart_application, ssl}]}, diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index 185a1f755a..000ceb241e 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -39,6 +39,8 @@ -include("ssl_internal.hrl"). -include("ssl_record.hrl"). +-include_lib("public_key/include/public_key.hrl"). + -record(config, {ssl, %% SSL parameters inet_user, %% User set inet options emulated, %% #socket_option{} emulated @@ -50,15 +52,18 @@ %% Function: start([, Type]) -> ok %% %% Type = permanent | transient | temporary -%% Vsns = [Vsn] -%% Vsn = ssl3 | tlsv1 | 'tlsv1.1' %% %% Description: Starts the ssl application. Default type %% is temporary. see application(3) %%-------------------------------------------------------------------- start() -> + application:start(crypto), + application:start(public_key), application:start(ssl). + start(Type) -> + application:start(crypto, Type), + application:start(public_key, Type), application:start(ssl, Type). %%-------------------------------------------------------------------- @@ -123,7 +128,7 @@ connect(Address, Port, Options0, Timeout) -> listen(_Port, []) -> {error, enooptions}; listen(Port, Options0) -> - case proplists:get_value(ssl_imp, Options0, old) of + case proplists:get_value(ssl_imp, Options0, new) of new -> new_listen(Port, Options0); old -> @@ -293,14 +298,7 @@ peercert(#sslsocket{pid = Pid, fd = new_ssl}, Opts) -> {ok, undefined} -> {error, no_peercert}; {ok, BinCert} -> - PKOpts = [case Opt of ssl -> otp; pkix -> plain end || - Opt <- Opts, Opt =:= ssl orelse Opt =:= pkix], - case PKOpts of - [Opt] -> - public_key:pkix_decode_cert(BinCert, Opt); - [] -> - {ok, BinCert} - end; + decode_peercert(BinCert, Opts); {error, Reason} -> {error, Reason} end; @@ -309,11 +307,40 @@ peercert(#sslsocket{} = Socket, Opts) -> ensure_old_ssl_started(), case ssl_broker:peercert(Socket) of {ok, Bin} -> - ssl_pkix:decode_cert(Bin, Opts); + decode_peercert(Bin, Opts); {error, Reason} -> {error, Reason} end. + +decode_peercert(BinCert, Opts) -> + PKOpts = [case Opt of ssl -> otp; pkix -> plain end || + Opt <- Opts, Opt =:= ssl orelse Opt =:= pkix], + case PKOpts of + [Opt] -> + select_part(Opt, public_key:pkix_decode_cert(BinCert, Opt), Opts); + [] -> + {ok, BinCert} + end. + +select_part(otp, {ok, Cert}, Opts) -> + case lists:member(subject, Opts) of + true -> + TBS = Cert#'OTPCertificate'.tbsCertificate, + {ok, TBS#'OTPTBSCertificate'.subject}; + false -> + {ok, Cert} + end; + +select_part(plain, {ok, Cert}, Opts) -> + case lists:member(subject, Opts) of + true -> + TBS = Cert#'Certificate'.tbsCertificate, + {ok, TBS#'TBSCertificate'.subject}; + false -> + {ok, Cert} + end. + %%-------------------------------------------------------------------- %% Function: peername(Socket) -> {ok, {Address, Port}} | {error, Reason} %% diff --git a/lib/ssl/src/ssl_base64.erl b/lib/ssl/src/ssl_base64.erl deleted file mode 100644 index cfc42407e8..0000000000 --- a/lib/ssl/src/ssl_base64.erl +++ /dev/null @@ -1,129 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2003-2009. 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 -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% - -%% - -%%% Purpose : Base 64 encoding and decoding. - --module(ssl_base64). - --export([encode/1, encode_split/1, decode/1, join_decode/1]). - --define(st(X,A), ((X-A+256) div 256)). --define(CHARS, 64). - -%% A PEM encoding consists of characters A-Z, a-z, 0-9, +, / and -%% =. Each character encodes a 6 bits value from 0 to 63 (A = 0, / = -%% 63); = is a padding character. -%% - -%% -%% encode(Bytes|Binary) -> Chars -%% -%% Take 3 bytes a time (3 x 8 = 24 bits), and make 4 characters out of -%% them (4 x 6 = 24 bits). -%% -encode(Bs) when is_list(Bs) -> - encode(list_to_binary(Bs)); -encode(<<B:3/binary, Bs/binary>>) -> - <<C1:6, C2:6, C3:6, C4:6>> = B, - [enc(C1), enc(C2), enc(C3), enc(C4)| encode(Bs)]; -encode(<<B:2/binary>>) -> - <<C1:6, C2:6, C3:6, _:6>> = <<B/binary, 0>>, - [enc(C1), enc(C2), enc(C3), $=]; -encode(<<B:1/binary>>) -> - <<C1:6, C2:6, _:12>> = <<B/binary, 0, 0>>, - [enc(C1), enc(C2), $=, $=]; -encode(<<>>) -> - []. - -%% -%% encode_split(Bytes|Binary) -> Lines -%% -%% The encoding is divided into lines separated by <NL>, and each line -%% is precisely 64 characters long (excluding the <NL> characters, -%% except the last line which 64 characters long or shorter. <NL> may -%% follow the last line. -%% -encode_split(Bs) -> - split(encode(Bs)). - -%% -%% decode(Chars) -> Binary -%% -decode(Cs) -> - list_to_binary(decode1(Cs)). - -decode1([C1, C2, $=, $=]) -> - <<B1, _:16>> = <<(dec(C1)):6, (dec(C2)):6, 0:12>>, - [B1]; -decode1([C1, C2, C3, $=]) -> - <<B1, B2, _:8>> = <<(dec(C1)):6, (dec(C2)):6, (dec(C3)):6, (dec(0)):6>>, - [B1, B2]; -decode1([C1, C2, C3, C4| Cs]) -> - Bin = <<(dec(C1)):6, (dec(C2)):6, (dec(C3)):6, (dec(C4)):6>>, - [Bin| decode1(Cs)]; -decode1([]) -> - []. - -%% -%% join_decode(Lines) -> Binary -%% -%% Remove <NL> before decoding. -%% -join_decode(Cs) -> - decode(join(Cs)). - -%% -%% Locals -%% - -%% enc/1 and dec/1 -%% -%% Mapping: 0-25 -> A-Z, 26-51 -> a-z, 52-61 -> 0-9, 62 -> +, 63 -> / -%% -enc(C) -> - 65 + C + 6*?st(C,26) - 75*?st(C,52) -15*?st(C,62) + 3*?st(C,63). - -dec(C) -> - 62*?st(C,43) + ?st(C,47) + (C-59)*?st(C,48) - 69*?st(C,65) - 6*?st(C,97). - -%% split encoding into lines -%% -split(Cs) -> - split(Cs, ?CHARS). - -split([], _N) -> - [$\n]; -split(Cs, 0) -> - [$\n| split(Cs, ?CHARS)]; -split([C| Cs], N) -> - [C| split(Cs, N-1)]. - -%% join lines of encodings -%% -join([$\r, $\n| Cs]) -> - join(Cs); -join([$\n| Cs]) -> - join(Cs); -join([C| Cs]) -> - [C| join(Cs)]; -join([]) -> - []. - diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index abd1b59011..07fa101ed4 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -125,8 +125,12 @@ recv(Pid, Length, Timeout) -> %% Description: Connect to a ssl server. %%-------------------------------------------------------------------- connect(Host, Port, Socket, Options, User, CbInfo, Timeout) -> - start_fsm(client, Host, Port, Socket, Options, User, CbInfo, - Timeout). + try start_fsm(client, Host, Port, Socket, Options, User, CbInfo, + Timeout) + catch + exit:{noproc, _} -> + {error, ssl_not_started} + end. %%-------------------------------------------------------------------- %% Function: accept(Port, Socket, Opts, User, %% CbInfo, Timeout) -> {ok, Socket} | {error, Reason} @@ -135,8 +139,12 @@ connect(Host, Port, Socket, Options, User, CbInfo, Timeout) -> %% ssl handshake. %%-------------------------------------------------------------------- ssl_accept(Port, Socket, Opts, User, CbInfo, Timeout) -> - start_fsm(server, "localhost", Port, Socket, Opts, User, - CbInfo, Timeout). + try start_fsm(server, "localhost", Port, Socket, Opts, User, + CbInfo, Timeout) + catch + exit:{noproc, _} -> + {error, ssl_not_started} + end. %%-------------------------------------------------------------------- %% Function: handshake(SslSocket, Timeout) -> ok | {error, Reason} @@ -1492,15 +1500,15 @@ handle_server_key( SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{client_random = ClientRandom, server_random = ServerRandom} = SecParams, - Plain = ssl_handshake:server_key_exchange_plain(KeyAlgo, - <<ClientRandom/binary, + Hash = ssl_handshake:server_key_exchange_hash(KeyAlgo, + <<ClientRandom/binary, ServerRandom/binary, - ?UINT16(PLen), P/binary, - ?UINT16(GLen), G/binary, - ?UINT16(YLen), + ?UINT16(PLen), P/binary, + ?UINT16(GLen), G/binary, + ?UINT16(YLen), ServerPublicDhKey/binary>>), - - case verify_dh_params(Signed, Plain, PubKeyInfo) of + + case verify_dh_params(Signed, Hash, PubKeyInfo) of true -> PMpint = mpint_binary(P), GMpint = mpint_binary(G), @@ -1533,8 +1541,8 @@ verify_dh_params(Signed, Hashes, {?rsaEncryption, PubKey, _PubKeyParams}) -> _ -> false end; -verify_dh_params(Signed, Plain, {?'id-dsa', PublicKey, PublicKeyParams}) -> - public_key:verify_signature(Plain, sha, Signed, PublicKey, PublicKeyParams). +verify_dh_params(Signed, Hash, {?'id-dsa', PublicKey, PublicKeyParams}) -> + public_key:verify_signature(Hash, none, Signed, PublicKey, PublicKeyParams). encode_alert(#alert{} = Alert, Version, ConnectionStates) -> diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index c8245e2fb4..f7e3e392ec 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -35,7 +35,7 @@ hello_request/0, certify/7, certificate/3, client_certificate_verify/6, certificate_verify/6, certificate_request/2, - key_exchange/2, server_key_exchange_plain/2, finished/4, + key_exchange/2, server_key_exchange_hash/2, finished/4, verify_connection/5, get_tls_handshake/4, server_hello_done/0, sig_alg/1, @@ -371,13 +371,13 @@ key_exchange(server, {dh, {<<?UINT32(Len), PublicKey:Len/binary>>, _}, YLen = byte_size(PublicKey), ServerDHParams = #server_dh_params{dh_p = PBin, dh_g = GBin, dh_y = PublicKey}, - Plain = - server_key_exchange_plain(KeyAlgo, <<ClientRandom/binary, + Hash = + server_key_exchange_hash(KeyAlgo, <<ClientRandom/binary, ServerRandom/binary, ?UINT16(PLen), PBin/binary, ?UINT16(GLen), GBin/binary, ?UINT16(YLen), PublicKey/binary>>), - Signed = digitally_signed(Plain, PrivateKey), + Signed = digitally_signed(Hash, PrivateKey), #server_key_exchange{params = ServerDHParams, signed_params = Signed}. @@ -1087,12 +1087,12 @@ certificate_authorities_from_db(CertDbRef, PrevKey, Acc) -> certificate_authorities_from_db(CertDbRef, Key, Acc) end. -digitally_signed(Hashes, #'RSAPrivateKey'{} = Key) -> - public_key:encrypt_private(Hashes, Key, +digitally_signed(Hash, #'RSAPrivateKey'{} = Key) -> + public_key:encrypt_private(Hash, Key, [{rsa_pad, rsa_pkcs1_padding}]); -digitally_signed(Plain, #'DSAPrivateKey'{} = Key) -> - public_key:sign(Plain, Key). - +digitally_signed(Hash, #'DSAPrivateKey'{} = Key) -> + public_key:sign(none, Hash, Key). + calc_master_secret({3,0}, PremasterSecret, ClientRandom, ServerRandom) -> ssl_ssl3:master_secret(PremasterSecret, ClientRandom, ServerRandom); @@ -1122,15 +1122,14 @@ calc_certificate_verify({3, N}, _, Algorithm, Hashes) when N == 1; N == 2 -> ssl_tls1:certificate_verify(Algorithm, Hashes). -server_key_exchange_plain(Algorithm, Value) when Algorithm == rsa; +server_key_exchange_hash(Algorithm, Value) when Algorithm == rsa; Algorithm == dhe_rsa -> MD5 = crypto:md5(Value), SHA = crypto:sha(Value), <<MD5/binary, SHA/binary>>; -server_key_exchange_plain(dhe_dss, Value) -> - %% Hash will be done by crypto. - Value. +server_key_exchange_hash(dhe_dss, Value) -> + crypto:sha(Value). sig_alg(dh_anon) -> ?SIGNATURE_ANONYMOUS; diff --git a/lib/ssl/src/ssl_pem.erl b/lib/ssl/src/ssl_pem.erl deleted file mode 100644 index 0a1bf0f32a..0000000000 --- a/lib/ssl/src/ssl_pem.erl +++ /dev/null @@ -1,147 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2003-2009. 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 -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% - -%% - --module(ssl_pem). - -%%% Purpose: Reading and writing of PEM type encoded files for SSL. - -%% NB write_file/2 is only preliminary. - -%% PEM encoded files have the following structure: -%% -%% <text> -%% -----BEGIN SOMETHING-----<CR><LF> -%% <Base64 encoding line><CR><LF> -%% <Base64 encoding line><CR><LF> -%% ... -%% -----END SOMETHING-----<CR><LF> -%% <text> -%% -%% A file can contain several BEGIN/END blocks. Text lines between -%% blocks are ignored. - --export([read_file/1, read_file/2, write_file/2]). - -%% Read a PEM file and return each decoding as a binary. - -read_file(File) -> - read_file(File, no_passwd). - -read_file(File, Passwd) -> - {ok, Fd} = file:open(File, [read]), - Result = decode_file(Fd, Passwd), - file:close(Fd), - Result. - -decode_file(Fd, Passwd) -> - decode_file(Fd, [], [], notag, [Passwd]). - -decode_file(Fd, _RLs, Ens, notag, Info) -> - case io:get_line(Fd, "") of - "-----BEGIN CERTIFICATE REQUEST-----" ++ _ -> - decode_file(Fd, [], Ens, cert_req, Info); - "-----BEGIN CERTIFICATE-----" ++ _ -> - decode_file(Fd, [], Ens, cert, Info); - "-----BEGIN RSA PRIVATE KEY-----" ++ _ -> - decode_file(Fd, [], Ens, rsa_private_key, Info); - eof -> - {ok, lists:reverse(Ens)}; - _ -> - decode_file(Fd, [], Ens, notag, Info) - end; -decode_file(Fd, RLs, Ens, Tag, Info0) -> - case io:get_line(Fd, "") of - "Proc-Type: 4,ENCRYPTED"++_ -> - Info = dek_info(Fd, Info0), - decode_file(Fd, RLs, Ens, Tag, Info); - "-----END" ++ _ -> % XXX sloppy - Cs = lists:flatten(lists:reverse(RLs)), - Bin = ssl_base64:join_decode(Cs), - case Info0 of - [Password, Cipher, SaltHex | Info1] -> - Decoded = decode_key(Bin, Password, Cipher, unhex(SaltHex)), - decode_file(Fd, [], [{Tag, Decoded}| Ens], notag, Info1); - _ -> - decode_file(Fd, [], [{Tag, Bin}| Ens], notag, Info0) - end; - eof -> - {ok, lists:reverse(Ens)}; - L -> - decode_file(Fd, [L|RLs], Ens, Tag, Info0) - end. - -dek_info(Fd, Info) -> - Line = io:get_line(Fd, ""), - [_, DekInfo0] = string:tokens(Line, ": "), - DekInfo1 = string:tokens(DekInfo0, ",\n"), - Info ++ DekInfo1. - -unhex(S) -> - unhex(S, []). - -unhex("", Acc) -> - lists:reverse(Acc); -unhex([D1, D2 | Rest], Acc) -> - unhex(Rest, [erlang:list_to_integer([D1, D2], 16) | Acc]). - -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, - <<Key1:8/binary, Key2:8/binary, Key3:8/binary>> = Key, - crypto:des_ede3_cbc_decrypt(Key1, Key2, Key3, IV, Data). - -write_file(File, Ds) -> - file:write_file(File, encode_file(Ds)). - -encode_file(Ds) -> - [encode_file_1(D) || D <- Ds]. - -encode_file_1({cert, Bin}) -> - %% PKIX (X.509) - ["-----BEGIN CERTIFICATE-----\n", - ssl_base64:encode_split(Bin), - "-----END CERTIFICATE-----\n\n"]; -encode_file_1({cert_req, Bin}) -> - %% PKCS#10 - ["-----BEGIN CERTIFICATE REQUEST-----\n", - ssl_base64:encode_split(Bin), - "-----END CERTIFICATE REQUEST-----\n\n"]; -encode_file_1({rsa_private_key, Bin}) -> - %% PKCS#? - ["XXX Following key assumed not encrypted\n", - "-----BEGIN RSA PRIVATE KEY-----\n", - ssl_base64:encode_split(Bin), - "-----END RSA PRIVATE KEY-----\n\n"]. - -password_to_key(Data, Salt, KeyLen) -> - <<Key:KeyLen/binary, _/binary>> = - 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 - byte_size(M), <<Acc/binary, M/binary>>). diff --git a/lib/ssl/src/ssl_pkix.erl b/lib/ssl/src/ssl_pkix.erl deleted file mode 100644 index 8f540f74ad..0000000000 --- a/lib/ssl/src/ssl_pkix.erl +++ /dev/null @@ -1,307 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2003-2009. 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 -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% - -%%% Purpose : API module for decoding of certificates. - --module(ssl_pkix). - --include("ssl_pkix.hrl"). - --export([decode_cert_file/1, decode_cert_file/2, - decode_cert/1, decode_cert/2, encode_cert/1, encoded_tbs_cert/1, - signature_digest/1, decode_rsa_keyfile/2]). - -%% The public API is dprecated by public_key and -%% the internal application API is no longer used ssl. -%% So this file can be compleatly removed in R14. --deprecated({decode_cert_file, 1, next_major_release}). --deprecated({decode_cert_file, 2, next_major_release}). --deprecated({decode_cert, 1, next_major_release}). --deprecated({decode_cert, 2, next_major_release}). - -%%==================================================================== -%% API -%%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: decode_cert_file(File, <Opts>) -> {ok, Cert} | {ok, [Cert]} -%% -%% File = string() -%% Opts = [Opt] -%% Opt = pem | ssl | pkix - ssl and pkix are mutual exclusive -%% Cert = term() -%% -%% Description: Decodes certificats found in file <File>. -%% If the options list is empty the certificate is -%% returned as a DER encoded binary, i.e. {ok, Bin} is returned, where -%% Bin> is the provided input. The options pkix and ssl imply that the -%% certificate is returned as a parsed ASN.1 structure in the form of -%% an Erlang term. The ssl option gives a more elaborate return -%% structure, with more explicit information. In particular object -%% identifiers are replaced by atoms. The option subject implies that -%% only the subject's distinguished name part of the certificate is -%% returned. It can only be used together with the option pkix or the -%% option ssl. -%%-------------------------------------------------------------------- -decode_cert_file(File) -> - decode_cert_file(File, []). - -decode_cert_file(File, Opts) -> - case lists:member(pem, Opts) of - true -> - {ok, List} = ssl_pem:read_file(File), - Certs = [Bin || {cert, Bin} <- List], - NewOpts = lists:delete(pem, Opts), - Fun = fun(Cert) -> - {ok, Decoded} = decode_cert(Cert, NewOpts), - Decoded - end, - case lists:map(Fun, Certs) of - [DecodedCert] -> - {ok, DecodedCert}; - DecodedCerts -> - {ok, DecodedCerts} - end; - false -> - {ok, Bin} = file:read_file(File), - decode_cert(Bin, Opts) - end. -%%-------------------------------------------------------------------- -%% Function: decode_cert(Bin, <Opts>) -> {ok, Cert} -%% Bin - binary() -%% Opts = [Opt] -%% Opt = ssl | pkix | subject - ssl and pkix are mutual exclusive -%% Cert = term() -%% -%% Description: If the options list is empty the certificate is -%% returned as a DER encoded binary, i.e. {ok, Bin} is returned, where -%% Bin> is the provided input. The options pkix and ssl imply that the -%% certificate is returned as a parsed ASN.1 structure in the form of -%% an Erlang term. The ssl option gives a more elaborate return -%% structure, with more explicit information. In particular object -%% identifiers are replaced by atoms. The option subject implies that -%% only the subject's distinguished name part of the certificate is -%% returned. It can only be used together with the option pkix or the -%% option ssl. -%%-------------------------------------------------------------------- -decode_cert(Bin) -> - decode_cert(Bin, []). - -decode_cert(Bin, []) when is_binary(Bin) -> - {ok, Bin}; -decode_cert(Bin, Opts) when is_binary(Bin) -> - - {ok, Cert} = 'OTP-PKIX':decode('Certificate', Bin), - - case {lists:member(ssl, Opts), lists:member(pkix, Opts)} of - {true, false} -> - cert_return(transform(Cert, ssl), Opts); - {false, true} -> - cert_return(transform(Cert, pkix), Opts); - _ -> - {error, eoptions} - end. - -encode_cert(#'Certificate'{} = Cert) -> - {ok, List} = 'OTP-PKIX':encode('Certificate', Cert), - list_to_binary(List). - -decode_rsa_keyfile(KeyFile, Password) -> - {ok, List} = ssl_pem:read_file(KeyFile, Password), - [PrivatKey] = [Bin || {rsa_private_key, Bin} <- List], - 'OTP-PKIX':decode('RSAPrivateKey', PrivatKey). - -%%==================================================================== -%% Application internal API -%%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: encoded_tbs_cert(Cert) -> PKXCert -%% -%% Cert = binary() - Der encoded -%% PKXCert = binary() - Der encoded -%% -%% Description: Extracts the binary TBSCert from the binary Certificate. -%%-------------------------------------------------------------------- -encoded_tbs_cert(Cert) -> - {ok, PKIXCert} = - 'OTP-PKIX':decode_TBSCert_exclusive(Cert), - {'Certificate', - {'Certificate_tbsCertificate', EncodedTBSCert}, _, _} = PKIXCert, - EncodedTBSCert. - -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- - -cert_return(Cert, Opts) -> - case lists:member(subject, Opts) of - true -> - {ok, get_subj(Cert)}; - false -> - {ok, Cert} - end. - - -%% Transfrom from PKIX1-Explicit88 to SSL-PKIX. - -transform(#'Certificate'{signature = Signature, - signatureAlgorithm = SignatureAlgorithm, - tbsCertificate = TbsCertificate} = Cert, Type) -> - Cert#'Certificate'{tbsCertificate = transform(TbsCertificate, Type), - signatureAlgorithm = transform(SignatureAlgorithm, Type), - signature = transform(Signature, Type)}; - -%% -record('TBSCertificate',{ -%% version = asn1_DEFAULT, serialNumber, signature, issuer, validity, subject, -%% subjectPublicKeyInfo, issuerUniqueID = asn1_NOVALUE, -%% subjectUniqueID = asn1_NOVALUE, extensions = asn1_NOVALUE}). - -transform(#'TBSCertificate'{signature = Signature, issuer = Issuer, - subject = Subject, extensions = Extensions, - subjectPublicKeyInfo = SPKInfo} = TBSCert, Type) -> - TBSCert#'TBSCertificate'{signature = transform(Signature, Type), - issuer = transform(Issuer, Type), - subject = transform(Subject, Type), - subjectPublicKeyInfo = transform(SPKInfo, Type), - extensions = transform_extensions(Extensions, Type) - }; - -transform(#'AlgorithmIdentifier'{algorithm = Algorithm, - parameters = Params}, ssl) -> - SignAlgAny = - #'SignatureAlgorithm-Any'{algorithm = Algorithm, parameters = Params}, - {ok, AnyEnc} = 'OTP-PKIX':encode('SignatureAlgorithm-Any', SignAlgAny), - {ok, SignAlgCd} = 'OTP-PKIX':decode('SignatureAlgorithm', - list_to_binary(AnyEnc)), - NAlgo = ssl_pkix_oid:id2atom(SignAlgCd#'SignatureAlgorithm'.algorithm), - SignAlgCd#'SignatureAlgorithm'{algorithm = NAlgo}; - -transform({rdnSequence, Lss}, Type) when is_list(Lss) -> - {rdnSequence, [[transform(L, Type) || L <- Ls] || Ls <- Lss]}; -transform({rdnSequence, Lss}, _) -> - {rdnSequence, Lss}; - -transform(#'AttributeTypeAndValue'{} = ATAV, ssl) -> - {ok, ATAVEnc} = - 'OTP-PKIX':encode('AttributeTypeAndValue', ATAV), - {ok, ATAVDec} = 'OTP-PKIX':decode('SSLAttributeTypeAndValue', - list_to_binary(ATAVEnc)), - AttrType = ATAVDec#'SSLAttributeTypeAndValue'.type, - #'AttributeTypeAndValue'{type = ssl_pkix_oid:id2atom(AttrType), - value = - ATAVDec#'SSLAttributeTypeAndValue'.value}; - -transform(#'AttributeTypeAndValue'{} = Att, pkix) -> - Att; - -%% -record('SubjectPublicKeyInfo',{ -%% algorithm, subjectPublicKey}). -%% -%% -record('SubjectPublicKeyInfo_algorithm',{ -%% algo, parameters = asn1_NOVALUE}). -%% -%% -record('SubjectPublicKeyInfo-Any',{ -%% algorithm, subjectPublicKey}). -%% -%% -record('PublicKeyAlgorithm',{ -%% algorithm, parameters = asn1_NOVALUE}). - -transform(#'SubjectPublicKeyInfo'{subjectPublicKey = SubjectPublicKey, - algorithm = Algorithm}, ssl) -> - %% Transform from SubjectPublicKeyInfo (PKIX1Explicit88) - %% to SubjectPublicKeyInfo-Any (SSL-PKIX). - Algo = Algorithm#'AlgorithmIdentifier'.algorithm, - Parameters = Algorithm#'AlgorithmIdentifier'.parameters, - AlgorithmAny = #'PublicKeyAlgorithm'{algorithm = Algo, - parameters = Parameters}, - {0, Bin} = SubjectPublicKey, - SInfoAny = #'SSLSubjectPublicKeyInfo-Any'{algorithm = AlgorithmAny, - subjectPublicKey = Bin}, - - %% Encode according to SubjectPublicKeyInfo-Any, and decode according - %% to SubjectPublicKeyInfo. - {ok, AnyEnc} = - 'OTP-PKIX':encode('SSLSubjectPublicKeyInfo-Any', SInfoAny), - {ok, SInfoCd} = 'OTP-PKIX':decode('SSLSubjectPublicKeyInfo', - list_to_binary(AnyEnc)), - %% Replace object identifier by atom - AlgorithmCd = SInfoCd#'SSLSubjectPublicKeyInfo'.algorithm, - AlgoCd = AlgorithmCd#'SSLSubjectPublicKeyInfo_algorithm'.algo, - Params = AlgorithmCd#'SSLSubjectPublicKeyInfo_algorithm'.parameters, - Key = SInfoCd#'SSLSubjectPublicKeyInfo'.subjectPublicKey, - NAlgoCd = ssl_pkix_oid:id2atom(AlgoCd), - NAlgorithmCd = - #'SubjectPublicKeyInfo_algorithm'{algorithm = NAlgoCd, - parameters = Params}, - #'SubjectPublicKeyInfo'{algorithm = NAlgorithmCd, - subjectPublicKey = Key - }; -transform(#'SubjectPublicKeyInfo'{} = SInfo, pkix) -> - SInfo; - -transform(#'Extension'{extnID = ExtnID} = Ext, ssl) -> - NewExtID = ssl_pkix_oid:id2atom(ExtnID), - ExtAny = setelement(1, Ext, 'Extension-Any'), - {ok, AnyEnc} = 'OTP-PKIX':encode('Extension-Any', ExtAny), - {ok, ExtCd} = 'OTP-PKIX':decode('SSLExtension', list_to_binary(AnyEnc)), - - ExtValue = transform_extension_value(NewExtID, - ExtCd#'SSLExtension'.extnValue, - ssl), - #'Extension'{extnID = NewExtID, - critical = ExtCd#'SSLExtension'.critical, - extnValue = ExtValue}; - -transform(#'Extension'{extnID = ExtnID, extnValue = ExtnValue} = Ext, pkix) -> - NewExtID = ssl_pkix_oid:id2atom(ExtnID), - ExtValue = transform_extension_value(NewExtID, ExtnValue, pkix), - Ext#'Extension'{extnValue = ExtValue}; - -transform(#'AuthorityKeyIdentifier'{authorityCertIssuer = CertIssuer} = Ext, - Type) -> - Ext#'AuthorityKeyIdentifier'{authorityCertIssuer = - transform(CertIssuer, Type)}; - -transform([{directoryName, Value}], Type) -> - [{directoryName, transform(Value, Type)}]; - -transform(X, _) -> - X. - -transform_extension_value('ce-authorityKeyIdentifier', Value, Type) -> - transform(Value, Type); -transform_extension_value(_, Value, _) -> - Value. - -transform_extensions(Exts, Type) when is_list(Exts) -> - [transform(Ext, Type) || Ext <- Exts]; -transform_extensions(Exts, _) -> - Exts. - -get_subj(Cert) -> - (Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject. - -signature_digest(BinSignature) -> - case (catch 'OTP-PKIX':decode('DigestInfo', BinSignature)) of - {ok, DigestInfo} -> - list_to_binary(DigestInfo#'DigestInfo'.digest); - _ -> - {error, decode_error} - end. diff --git a/lib/ssl/src/ssl_pkix.hrl b/lib/ssl/src/ssl_pkix.hrl deleted file mode 100644 index a8463369f6..0000000000 --- a/lib/ssl/src/ssl_pkix.hrl +++ /dev/null @@ -1,81 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2003-2009. 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 -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% - -%% - --ifndef(ssl_pkix). --define(ssl_pkix, true). - --include("OTP-PKIX.hrl"). - -%% The following commented out records are currently defined in OTP-PKIX.hrl -%% and are considered a public interface through ssl_pkix.hrl. -%% NOTE do not include OTP-PKIX.hrl it is an generated file -%% and may change but the following records will still be -%% availanble from this file. - -% -record('Certificate', { -% tbsCertificate, -% signatureAlgorithm, -% signature}). - -% -record('TBSCertificate', { -% version = asn1_DEFAULT, -% serialNumber, -% signature, -% issuer, -% validity, -% subject, -% subjectPublicKeyInfo, -% issuerUniqueID = asn1_NOVALUE, -% subjectUniqueID = asn1_NOVALUE, -% extensions = asn1_NOVALUE}). - -% -record('AttributeTypeAndValue', { -% type, -% value}). - -% -record('SubjectPublicKeyInfo', { -% algorithm, -% subjectPublicKey}). - --record('SubjectPublicKeyInfo_algorithm', { - algorithm, - parameters = asn1_NOVALUE}). - -% -record('FieldID', { -% fieldType, -% parameters}). - -% -record('Characteristic-two', { -% m, -% basis, -% parameters}). - -% -record('ExtensionAttribute', { -% extensionAttributeType, -% extensionAttributeValue}). - -% -record('Extension', { -% extnID, -% critical = asn1_DEFAULT, -% extnValue}). - --endif. % -ifdef(ssl_pkix). - diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl index 400298a322..88b801d46b 100644 --- a/lib/ssl/src/ssl_ssl3.erl +++ b/lib/ssl/src/ssl_ssl3.erl @@ -147,7 +147,7 @@ suites() -> ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA, ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA, ?TLS_RSA_WITH_AES_128_CBC_SHA, - ?TLS_RSA_WITH_IDEA_CBC_SHA, + %%?TLS_RSA_WITH_IDEA_CBC_SHA, ?TLS_RSA_WITH_RC4_128_SHA, ?TLS_RSA_WITH_RC4_128_MD5, ?TLS_RSA_WITH_DES_CBC_SHA |