diff options
Diffstat (limited to 'lib/public_key')
-rw-r--r-- | lib/public_key/doc/specs/.gitignore | 1 | ||||
-rw-r--r-- | lib/public_key/doc/src/Makefile | 7 | ||||
-rw-r--r-- | lib/public_key/doc/src/public_key.xml | 684 | ||||
-rw-r--r-- | lib/public_key/doc/src/specs.xml | 4 | ||||
-rw-r--r-- | lib/public_key/src/public_key.erl | 439 | ||||
-rw-r--r-- | lib/public_key/test/public_key_SUITE.erl | 4 |
6 files changed, 521 insertions, 618 deletions
diff --git a/lib/public_key/doc/specs/.gitignore b/lib/public_key/doc/specs/.gitignore new file mode 100644 index 0000000000..322eebcb06 --- /dev/null +++ b/lib/public_key/doc/specs/.gitignore @@ -0,0 +1 @@ +specs_*.xml diff --git a/lib/public_key/doc/src/Makefile b/lib/public_key/doc/src/Makefile index 03467e9783..8575b196b7 100644 --- a/lib/public_key/doc/src/Makefile +++ b/lib/public_key/doc/src/Makefile @@ -77,12 +77,18 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf +SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml) + +TOP_SPECS_FILE = specs.xml + # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- XML_FLAGS += DVIPS_FLAGS += +SPECS_FLAGS = -I../../include -I../../src -I../../.. + # ---------------------------------------------------- # Targets # ---------------------------------------------------- @@ -103,6 +109,7 @@ clean clean_docs: rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) + rm -f $(SPECS_FILES) rm -f errs core *~ man: $(MAN3_FILES) $(MAN6_FILES) diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index aaccb5088b..1b588018e4 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -41,7 +41,7 @@ </description> <section> - <title>DATA TYPES</title> + <title>Common Records and ASN.1 Types</title> <note><p>All records used in this Reference Manual <!-- except #policy_tree_node{} --> @@ -54,193 +54,132 @@ records and constant macros described here and in the User's Guide:</p> <code> -include_lib("public_key/include/public_key.hrl").</code> + </section> + + <datatypes> + <datatype> + <name name="oid"/> + <desc> + <p>Object identifier, a tuple of integers as generated by the <c>ASN.1</c> compiler.</p> + </desc> + </datatype> + + <datatype> + <name name="der_encoded"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="pki_asn1_type"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="asn1_type"/> + <desc> + <p>ASN.1 type present in the Public Key applications ASN.1 specifications.</p> + </desc> + </datatype> + + <datatype> + <name name="pem_entry"/> + <name name="der_or_encrypted_der"/> + <name name="cipher_info"/> + <name name="cipher"/> + <name name="salt"/> + <name name="cipher_info_params"/> + <desc> + <code>Cipher = "RC2-CBC" | "DES-CBC" | "DES-EDE3-CBC"</code> + <p><c>Salt</c> could be generated with + <seealso marker="crypto:crypto#strong_rand_bytes-1"><c>crypto:strong_rand_bytes(8)</c></seealso>.</p> + </desc> + </datatype> + + <datatype> + <name name="public_key"/> + <name name="rsa_public_key"/> + <name name="dsa_public_key"/> + <name name="ec_public_key"/> + <name name="ecpk_parameters"/> + <name name="ecpk_parameters_api"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="private_key"/> + <name name="rsa_private_key"/> + <name name="dsa_private_key"/> + <name name="ec_private_key"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="key_params"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="digest_type"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="crl_reason"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="issuer_id"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="issuer_name"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="ssh_file"/> + <desc> + </desc> + </datatype> + + + + </datatypes> - <p>The following data types are used in the functions for <c>public_key</c>:</p> - - <taglist> - <tag><c>oid()</c></tag> - <item><p>Object identifier, a tuple of integers as generated by the <c>ASN.1</c> compiler.</p></item> - - <tag><c>boolean() =</c></tag> - <item><p><c>true | false</c></p></item> - - <tag><c>string() =</c></tag> - <item><p><c>[bytes()]</c></p></item> - - <tag><c>der_encoded() =</c></tag> - <item><p><c>binary()</c></p></item> - - <tag><c>pki_asn1_type() =</c></tag> - <item> - <p><c>'Certificate'</c></p> - <p><c>| 'RSAPrivateKey'</c></p> - <p><c>| 'RSAPublicKey'</c></p> - <p><c>| 'DSAPrivateKey'</c></p> - <p><c>| 'DSAPublicKey'</c></p> - <p><c>| 'DHParameter'</c></p> - <p><c>| 'SubjectPublicKeyInfo'</c></p> - <p><c>| 'PrivateKeyInfo'</c></p> - <p><c>| 'CertificationRequest'</c></p> - <p><c>| 'CertificateList'</c></p> - <p><c>| 'ECPrivateKey'</c></p> - <p><c>| 'EcpkParameters'</c></p> - </item> - - <tag><c>pem_entry () =</c></tag> - <item><p><c>{pki_asn1_type(), binary(), %% DER or encrypted DER</c></p> - <p><c> not_encrypted | cipher_info()}</c></p></item> - - <tag><c>cipher_info() = </c></tag> - <item><p><c>{"RC2-CBC" | "DES-CBC" | "DES-EDE3-CBC", crypto:strong_rand_bytes(8)</c></p> - <p><c>| {#'PBEParameter{}, digest_type()} | #'PBES2-params'{}}</c></p> - </item> - - <tag><marker id="type-public_key"/> - <c>public_key() =</c></tag> - <item><p><c>rsa_public_key() | dsa_public_key() | ec_public_key()</c></p></item> - - <tag><marker id="type-private_key"/> - <c>private_key() =</c></tag> - <item><p><c>rsa_private_key() | dsa_private_key() | ec_private_key()</c></p></item> - - <tag><c>rsa_public_key() =</c></tag> - <item><p><c>#'RSAPublicKey'{}</c></p></item> - - <tag><c>rsa_private_key() =</c></tag> - <item><p><c>#'RSAPrivateKey'{}</c></p></item> - - <tag><c>dsa_public_key() =</c></tag> - <item><p><c>{integer(), #'Dss-Parms'{}}</c></p></item> - - <tag><c>dsa_private_key() =</c></tag> - <item><p><c>#'DSAPrivateKey'{}</c></p></item> - - <tag><c>ec_public_key()</c></tag> - <item><p>= <c>{#'ECPoint'{}, #'ECParameters'{} | {namedCurve, oid()}}</c></p></item> - - <tag><c>ec_private_key() =</c></tag> - <item><p><c>#'ECPrivateKey'{}</c></p></item> - - <tag><c>key_params() =</c></tag> - <item><p> #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{} - | {rsa, Size::integer(), PubExp::integer()} </p></item> - - <tag><c>public_crypt_options() =</c></tag> - <item><p><c>[{rsa_pad, rsa_padding()}]</c></p></item> - - <tag><c>rsa_padding() =</c></tag> - <item> - <p><c>'rsa_pkcs1_padding'</c></p> - <p><c>| 'rsa_pkcs1_oaep_padding'</c></p> - <p><c>| 'rsa_no_padding'</c></p> - </item> - - <tag><c>public_sign_options() =</c></tag> - <item><p><c>[{rsa_pad, rsa_sign_padding()} | {rsa_pss_saltlen, integer()}]</c></p></item> - - <tag><c>rsa_sign_padding() =</c></tag> - <item> - <p><c>'rsa_pkcs1_padding'</c></p> - <p><c>| 'rsa_pkcs1_pss_padding'</c></p> - </item> - - <tag><c>digest_type() = </c></tag> - <item><p>Union of <c>rsa_digest_type()</c>, <c>dss_digest_type()</c>, - and <c>ecdsa_digest_type()</c>.</p></item> - - <tag><c>rsa_digest_type() = </c></tag> - <item><p><c>'md5' | 'ripemd160' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'</c></p></item> - - <tag><c>dss_digest_type() = </c></tag> - <item><p><c>'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'</c></p> - <p>Note that the actual supported dss_digest_type depends on the underlying crypto library. - In OpenSSL version >= 1.0.1 the listed digest are supported, while in 1.0.0 only - sha, sha224 and sha256 are supported. In version 0.9.8 only sha is supported.</p> - </item> - - <tag><c>ecdsa_digest_type() = </c></tag> - <item><p><c>'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'</c></p></item> - - <tag><c>crl_reason() = </c></tag> - <item> - <p><c>unspecified</c></p> - <p><c>| keyCompromise</c></p> - <p><c>| cACompromise</c></p> - <p><c>| affiliationChanged</c></p> - <p><c>| superseded</c></p> - <p><c>| cessationOfOperation</c></p> - <p><c>| certificateHold</c></p> - <p><c>| privilegeWithdrawn</c></p> - <p><c>| aACompromise</c></p> - </item> - - <tag><c>issuer_name() =</c></tag> - <item><p><c>{rdnSequence,[#'AttributeTypeAndValue'{}]}</c></p> - </item> - - <tag><c>ssh_file() =</c></tag> - <item> - <p><c>openssh_public_key</c></p> - <p><c>| rfc4716_public_key</c></p> - <p><c>| known_hosts</c></p> - <p><c>| auth_keys</c></p> - </item> - </taglist> - - -<!-- <p><code>policy_tree() = [Root, Children]</code></p> --> - -<!-- <p><code>Root = #policy_tree_node{}</code></p> --> - -<!-- <p><code>Children = [] | policy_tree()</code></p> --> - -<!-- <p>The <c>policy_tree_node</c> record has the following fields:</p> --> - -<!-- <taglist> --> - -<!-- <tag>valid_policy</tag> --> -<!-- <item>A single policy OID representing a --> -<!-- valid policy for the path of length x.</item> --> - -<!-- <tag>qualifier_set</tag> --> -<!-- <item>A set of policy qualifiers associated --> -<!-- with the valid policy in certificate x.</item> --> - -<!-- <tag>critically_indicator</tag> --> -<!-- <item>Indicates whether the --> -<!-- certificate policy extension in certificate x was marked as --> -<!-- critical.</item> --> - -<!-- <tag>expected_policy_set</tag> --> -<!-- <item>Contains one or more policy OIDs --> -<!-- that would satisfy this policy in the certificate x+1.</item> --> -<!-- </taglist> --> - </section> <funcs> <func> - <name>compute_key(OthersKey, MyKey)-></name> - <name>compute_key(OthersKey, MyKey, Params)-></name> + <name name="compute_key" arity="2"/> + <fsummary>Computes shared secret.</fsummary> + <desc> + <p>Computes shared secret.</p> + </desc> + </func> + + <func> + <name name="compute_key" arity="3"/> <fsummary>Computes shared secret.</fsummary> - <type> - <v>OthersKey = #'ECPoint'{} | binary(), MyKey = #'ECPrivateKey'{} | binary()</v> - <v>Params = #'DHParameter'{}</v> - </type> <desc> <p>Computes shared secret.</p> </desc> </func> <func> - <name>decrypt_private(CipherText, Key) -> binary()</name> - <name>decrypt_private(CipherText, Key, Options) -> binary()</name> + <name name="decrypt_private" arity="2"/> + <name name="decrypt_private" arity="3"/> <fsummary>Public-key decryption.</fsummary> - <type> - <v>CipherText = binary()</v> - <v>Key = rsa_private_key()</v> - <v>Options = public_crypt_options()</v> - </type> <desc> <p>Public-key decryption using the private key. See also <seealso marker="crypto:crypto#private_decrypt/4">crypto:private_decrypt/4</seealso></p> @@ -248,14 +187,9 @@ </func> <func> - <name>decrypt_public(CipherText, Key) - > binary()</name> - <name>decrypt_public(CipherText, Key, Options) - > binary()</name> + <name name="decrypt_public" arity="2"/> + <name name="decrypt_public" arity="3"/> <fsummary>Public-key decryption.</fsummary> - <type> - <v>CipherText = binary()</v> - <v>Key = rsa_public_key()</v> - <v>Options = public_crypt_options()</v> - </type> <desc> <p>Public-key decryption using the public key. See also <seealso marker="crypto:crypto#public_decrypt/4">crypto:public_decrypt/4</seealso></p> @@ -263,47 +197,24 @@ </func> <func> - <name>der_decode(Asn1type, Der) -> term()</name> + <name name="der_decode" arity="2"/> <fsummary>Decodes a public-key ASN.1 DER encoded entity.</fsummary> - <type> - <v>Asn1Type = atom()</v> - <d>ASN.1 type present in the Public Key applications - ASN.1 specifications.</d> - <v>Der = der_encoded()</v> - </type> - <desc> + <desc> <p>Decodes a public-key ASN.1 DER encoded entity.</p> </desc> </func> - + <func> - <name>der_encode(Asn1Type, Entity) -> der_encoded()</name> + <name name="der_encode" arity="2"/> <fsummary>Encodes a public-key entity with ASN.1 DER encoding.</fsummary> - <type> - <v>Asn1Type = atom()</v> - <d>ASN.1 type present in the Public Key applications - ASN.1 specifications.</d> - <v>Entity = term()</v> - <d>Erlang representation of <c>Asn1Type</c></d> - </type> <desc> <p>Encodes a public-key entity with ASN.1 DER encoding.</p> </desc> </func> <func> - <name>dh_gex_group(MinSize, SuggestedSize, MaxSize, Groups) -> {ok, {Size,Group}} | {error,Error}</name> + <name name="dh_gex_group" arity="4"/> <fsummary>Selects a group for Diffie-Hellman key exchange</fsummary> - <type> - <v>MinSize = positive_integer()</v> - <v>SuggestedSize = positive_integer()</v> - <v>MaxSize = positive_integer()</v> - <v>Groups = undefined | [{Size,[{G,P}]}]</v> - <v>Size = positive_integer()</v> - <v>Group = {G,P}</v> - <v>G = positive_integer()</v> - <v>P = positive_integer()</v> - </type> <desc> <p>Selects a group for Diffie-Hellman key exchange with the key size in the range <c>MinSize...MaxSize</c> and as close to <c>SuggestedSize</c> as possible. If <c>Groups == undefined</c> a default set will be @@ -322,13 +233,10 @@ </desc> </func> - <func> - <name>encrypt_private(PlainText, Key) -> binary()</name> + <func> + <name name="encrypt_private" arity="2"/> + <name name="encrypt_private" arity="3"/> <fsummary>Public-key encryption using the private key.</fsummary> - <type> - <v>PlainText = binary()</v> - <v>Key = rsa_private_key()</v> - </type> <desc> <p>Public-key encryption using the private key. See also <seealso @@ -337,12 +245,9 @@ </func> <func> - <name>encrypt_public(PlainText, Key) -> binary()</name> + <name name="encrypt_public" arity="2"/> + <name name="encrypt_public" arity="3"/> <fsummary>Public-key encryption using the public key.</fsummary> - <type> - <v>PlainText = binary()</v> - <v>Key = rsa_public_key()</v> - </type> <desc> <p>Public-key encryption using the public key. See also <seealso marker="crypto:crypto#public_encrypt/4">crypto:public_encrypt/4</seealso>.</p> @@ -350,11 +255,8 @@ </func> <func> - <name>generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{} | #'RSAPrivateKey'{}</name> + <name name="generate_key" arity="1"/> <fsummary>Generates a new keypair.</fsummary> - <type> - <v>Params = key_params()</v> - </type> <desc> <p>Generates a new keypair. Note that except for Diffie-Hellman the public key is included in the private key structure. See also @@ -364,38 +266,27 @@ </func> <func> - <name>pem_decode(PemBin) -> [pem_entry()]</name> + <name name="pem_decode" arity="1"/> <fsummary>Decodes PEM binary data and returns entries as ASN.1 DER encoded entities.</fsummary> - <type> - <v>PemBin = binary()</v> - <d>Example {ok, PemBin} = file:read_file("cert.pem").</d> - </type> <desc> - <p>Decodes PEM binary data and returns - entries as ASN.1 DER encoded entities.</p> + <p>Decodes PEM binary data and returns entries as ASN.1 DER encoded entities.</p> + <p>Example <c>{ok, PemBin} = file:read_file("cert.pem").</c></p> </desc> </func> - <func> - <name>pem_encode(PemEntries) -> binary()</name> + <func> + <name name="pem_encode" arity="1"/> <fsummary>Creates a PEM binary.</fsummary> - <type> - <v> PemEntries = [pem_entry()] </v> - </type> - <desc> - <p>Creates a PEM binary.</p> - </desc> + <desc> + <p>Creates a PEM binary.</p> + </desc> </func> - <func> - <name>pem_entry_decode(PemEntry) -> term()</name> - <name>pem_entry_decode(PemEntry, Password) -> term()</name> + <func> + <name name="pem_entry_decode" arity="1"/> + <name name="pem_entry_decode" arity="2"/> <fsummary>Decodes a PEM entry.</fsummary> - <type> - <v>PemEntry = pem_entry()</v> - <v>Password = string()</v> - </type> <desc> <p>Decodes a PEM entry. <c>pem_decode/1</c> returns a list of PEM entries. Notice that if the PEM entry is of type @@ -404,51 +295,36 @@ </desc> </func> - <func> - <name>pem_entry_encode(Asn1Type, Entity) -> pem_entry()</name> - <name>pem_entry_encode(Asn1Type, Entity, {CipherInfo, Password}) -> pem_entry()</name> + <func> + <name name="pem_entry_encode" arity="2"/> + <name name="pem_entry_encode" arity="3"/> <fsummary>Creates a PEM entry that can be fed to <c>pem_encode/1</c>.</fsummary> - <type> - <v>Asn1Type = pki_asn1_type()</v> - <v>Entity = term()</v> - <d>Erlang representation of - <c>Asn1Type</c>. If <c>Asn1Type</c> is 'SubjectPublicKeyInfo', + <desc> + <p>Creates a PEM entry that can be feed to <c>pem_encode/1</c>.</p> + <p>If <c>Asn1Type</c> is <c>'SubjectPublicKeyInfo'</c>, <c>Entity</c> must be either an <c>rsa_public_key()</c>, <c>dsa_public_key()</c> or an <c>ec_public_key()</c> and this function creates the appropriate - 'SubjectPublicKeyInfo' entry. - </d> - <v>CipherInfo = cipher_info()</v> - <v>Password = string()</v> - </type> - <desc> - <p>Creates a PEM entry that can be feed to <c>pem_encode/1</c>.</p> - </desc> + <c>'SubjectPublicKeyInfo'</c> entry. + </p> + </desc> </func> - + <func> - <name>pkix_decode_cert(Cert, otp|plain) -> #'Certificate'{} | #'OTPCertificate'{}</name> + <name name="pkix_decode_cert" arity="2"/> <fsummary>Decodes an ASN.1 DER-encoded PKIX x509 certificate.</fsummary> - <type> - <v>Cert = der_encoded()</v> - </type> - <desc> - <p>Decodes an ASN.1 DER-encoded PKIX certificate. Option <c>otp</c> - uses the customized ASN.1 specification OTP-PKIX.asn1 for - decoding and also recursively decode most of the standard - parts.</p> - </desc> + <desc> + <p>Decodes an ASN.1 DER-encoded PKIX certificate. Option <c>otp</c> + uses the customized ASN.1 specification OTP-PKIX.asn1 for + decoding and also recursively decode most of the standard + parts.</p> + </desc> </func> <func> - <name>pkix_encode(Asn1Type, Entity, otp | plain) -> der_encoded()</name> + <name name="pkix_encode" arity="3"/> <fsummary>DER encodes a PKIX x509 certificate or part of such a certificate.</fsummary> - <type> - <v>Asn1Type = atom()</v> - <d>The ASN.1 type can be 'Certificate', 'OTPCertificate' or a subtype of either.</d> - <v>Entity = #'Certificate'{} | #'OTPCertificate'{} | a valid subtype</v> - </type> <desc> <p>DER encodes a PKIX x509 certificate or part of such a certificate. This function must be used for encoding certificates or parts of certificates @@ -458,69 +334,47 @@ </func> <func> - <name>pkix_is_issuer(Cert, IssuerCert) -> boolean()</name> - <fsummary>Checks if <c>IssuerCert</c> issued <c>Cert</c>.</fsummary> - <type> - <v>Cert = der_encoded() | #'OTPCertificate'{} | #'CertificateList'{}</v> - <v>IssuerCert = der_encoded() | #'OTPCertificate'{}</v> - </type> - <desc> - <p>Checks if <c>IssuerCert</c> issued <c>Cert</c>.</p> - </desc> - </func> + <name name="pkix_is_issuer" arity="2"/> + <fsummary>Checks if <c>IssuerCert</c> issued <c>Cert</c>.</fsummary> + <desc> + <p>Checks if <c>IssuerCert</c> issued <c>Cert</c>.</p> + </desc> + </func> - <func> - <name>pkix_is_fixed_dh_cert(Cert) -> boolean()</name> - <fsummary>Checks if a certificate is a fixed Diffie-Hellman certificate.</fsummary> - <type> - <v>Cert = der_encoded() | #'OTPCertificate'{}</v> - </type> - <desc> - <p>Checks if a certificate is a fixed Diffie-Hellman certificate.</p> - </desc> - </func> + <func> + <name name="pkix_is_fixed_dh_cert" arity="1"/> + <fsummary>Checks if a certificate is a fixed Diffie-Hellman certificate.</fsummary> + <desc> + <p>Checks if a certificate is a fixed Diffie-Hellman certificate.</p> + </desc> + </func> - <func> - <name>pkix_is_self_signed(Cert) -> boolean()</name> - <fsummary>Checks if a certificate is self-signed.</fsummary> - <type> - <v>Cert = der_encoded() | #'OTPCertificate'{}</v> - </type> - <desc> - <p>Checks if a certificate is self-signed.</p> - </desc> - </func> + <func> + <name name="pkix_is_self_signed" arity="1"/> + <fsummary>Checks if a certificate is self-signed.</fsummary> + <desc> + <p>Checks if a certificate is self-signed.</p> + </desc> + </func> - <func> - <name>pkix_issuer_id(Cert, IssuedBy) -> {ok, IssuerID} | {error, Reason}</name> - <fsummary>Returns the issuer id.</fsummary> - <type> - <v>Cert = der_encoded() | #'OTPCertificate'{}</v> - <v>IssuedBy = self | other</v> - <v>IssuerID = {integer(), issuer_name()}</v> - <d>The issuer id consists of the serial number and the issuers name.</d> - <v>Reason = term()</v> - </type> - <desc> - <p>Returns the issuer id.</p> - </desc> - </func> - + <func> + <name name="pkix_issuer_id" arity="2"/> + <fsummary>Returns the issuer id.</fsummary> + <desc> + <p>Returns the issuer id.</p> + </desc> + </func> - <func> - <name>pkix_normalize_name(Issuer) -> Normalized</name> - <fsummary>Normalizes an issuer name so that it can be easily - compared to another issuer name.</fsummary> - <type> - <v>Issuer = issuer_name()</v> - <v>Normalized = issuer_name()</v> - </type> - <desc> - <p>Normalizes an issuer name so that it can be easily - compared to another issuer name.</p> - </desc> - </func> - + <func> + <name name="pkix_normalize_name" arity="1"/> + <fsummary>Normalizes an issuer name so that it can be easily + compared to another issuer name.</fsummary> + <desc> + <p>Normalizes an issuer name so that it can be easily + compared to another issuer name.</p> + </desc> + </func> + <func> <name>pkix_path_validation(TrustedCert, CertChain, Options) -> {ok, {PublicKeyInfo, PolicyTree}} | {error, {bad_cert, Reason}} </name> <fsummary>Performs a basic path validation according to RFC 5280.</fsummary> @@ -622,26 +476,16 @@ fun(OtpCert :: #'OTPCertificate'{}, </func> <func> - <name>pkix_crl_issuer(CRL) -> issuer_name()</name> + <name name="pkix_crl_issuer" arity="1"/> <fsummary>Returns the issuer of the <c>CRL</c>.</fsummary> - <type> - <v>CRL = der_encoded() | #'CertificateList'{} </v> - </type> <desc> <p>Returns the issuer of the <c>CRL</c>.</p> </desc> </func> <func> - <name>pkix_crls_validate(OTPCertificate, DPAndCRLs, Options) -> CRLStatus()</name> + <name name="pkix_crls_validate" arity="3"/> <fsummary>Performs CRL validation.</fsummary> - <type> - <v>OTPCertificate = #'OTPCertificate'{}</v> - <v>DPAndCRLs = [{DP::#'DistributionPoint'{}, {DerCRL::der_encoded(), CRL::#'CertificateList'{}}}] </v> - <v>Options = proplists:proplist()</v> - <v>CRLStatus() = valid | {bad_cert, revocation_status_undetermined} | {bad_cert, {revocation_status_undetermined, - {bad_crls, Details::term()}}} | {bad_cert, {revoked, crl_reason()}}</v> - </type> <desc> <p>Performs CRL validation. It is intended to be called from the verify fun of <seealso marker="#pkix_path_validation-3"> pkix_path_validation/3 @@ -692,24 +536,16 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, </func> <func> - <name>pkix_crl_verify(CRL, Cert) -> boolean()</name> + <name name="pkix_crl_verify" arity="2"/> <fsummary> Verify that <c>Cert</c> is the <c> CRL</c> signer. </fsummary> - <type> - <v>CRL = der_encoded() | #'CertificateList'{} </v> - <v>Cert = der_encoded() | #'OTPCertificate'{} </v> - </type> <desc> <p>Verify that <c>Cert</c> is the <c>CRL</c> signer.</p> </desc> </func> <func> - <name>pkix_dist_point(Cert) -> DistPoint</name> + <name name="pkix_dist_point" arity="1"/> <fsummary>Creates a distribution point for CRLs issued by the same issuer as <c>Cert</c>.</fsummary> - <type> - <v> Cert = der_encoded() | #'OTPCertificate'{} </v> - <v> DistPoint = #'DistributionPoint'{}</v> - </type> <desc> <p>Creates a distribution point for CRLs issued by the same issuer as <c>Cert</c>. Can be used as input to <seealso @@ -719,26 +555,17 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, </func> <func> - <name>pkix_dist_points(Cert) -> DistPoints</name> + <name name="pkix_dist_points" arity="1"/> <fsummary> Extracts distribution points from the certificates extensions.</fsummary> - <type> - <v> Cert = der_encoded() | #'OTPCertificate'{} </v> - <v> DistPoints = [#'DistributionPoint'{}]</v> - </type> <desc> <p> Extracts distribution points from the certificates extensions.</p> </desc> </func> <func> - <name>pkix_match_dist_point(CRL, DistPoint) -> boolean()</name> + <name name="pkix_match_dist_point" arity="2"/> <fsummary>Checks whether the given distribution point matches the Issuing Distribution Point of the CRL.</fsummary> - - <type> - <v>CRL = der_encoded() | #'CertificateList'{} </v> - <v>DistPoint = #'DistributionPoint'{}</v> - </type> <desc> <p>Checks whether the given distribution point matches the Issuing Distribution Point of the CRL, as described in RFC 5280. @@ -748,11 +575,8 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, </func> <func> - <name>pkix_sign(#'OTPTBSCertificate'{}, Key) -> der_encoded()</name> + <name name="pkix_sign" arity="2"/> <fsummary>Signs certificate.</fsummary> - <type> - <v>Key = rsa_private_key() | dsa_private_key()</v> - </type> <desc> <p>Signs an 'OTPTBSCertificate'. Returns the corresponding DER-encoded certificate.</p> @@ -760,17 +584,12 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, </func> <func> - <name>pkix_sign_types(AlgorithmId) -> {DigestType, SignatureType}</name> + <name name="pkix_sign_types" arity="1"/> <fsummary>Translates signature algorithm OID to Erlang digest and signature algorithm types.</fsummary> - <type> - <v>AlgorithmId = oid()</v> - <d>Signature OID from a certificate or a certificate revocation list.</d> - <v>DigestType = rsa_digest_type() | dss_digest_type()</v> - <v>SignatureType = rsa | dsa | ecdsa</v> - </type> <desc> <p>Translates signature algorithm OID to Erlang digest and signature types. </p> + <p>The <c>AlgorithmId</c> is the signature OID from a certificate or a certificate revocation list.</p> </desc> </func> @@ -938,12 +757,8 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, </func> <func> - <name>pkix_verify(Cert, Key) -> boolean()</name> + <name name="pkix_verify" arity="2"/> <fsummary>Verifies PKIX x.509 certificate signature.</fsummary> - <type> - <v>Cert = der_encoded()</v> - <v>Key = rsa_public_key() | dsa_public_key() | ec_public_key()</v> - </type> <desc> <p>Verifies PKIX x.509 certificate signature.</p> </desc> @@ -1059,41 +874,30 @@ end <func> - <name>sign(Msg, DigestType, Key) -> binary()</name> - <name>sign(Msg, DigestType, Key, Options) -> binary()</name> + <name name="sign" arity="3"/> + <name name="sign" arity="4"/> <fsummary>Creates a digital signature.</fsummary> - <type> - <v>Msg = binary() | {digest,binary()}</v> - <d>The <c>Msg</c> is either the binary "plain text" data to be - signed or it is the hashed value of "plain text", that is, the - digest.</d> - <v>DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()</v> - <v>Key = rsa_private_key() | dsa_private_key() | ec_private_key()</v> - <v>Options = public_sign_options()</v> - </type> <desc> <p>Creates a digital signature.</p> + <p>The <c>Msg</c> is either the binary "plain text" data to be + signed or it is the hashed value of "plain text", that is, the + digest.</p> </desc> </func> <func> - <name>ssh_decode(SshBin, Type) -> [{public_key(), Attributes::list()}]</name> + <name name="ssh_decode" arity="2"/> <fsummary>Decodes an SSH file-binary.</fsummary> - <type> - <v>SshBin = binary()</v> - <d>Example <c>{ok, SshBin} = file:read_file("known_hosts")</c>.</d> - <v>Type = public_key | ssh_file()</v> - <d>If <c>Type</c> is <c>public_key</c> the binary can be either - an RFC4716 public key or an OpenSSH public key.</d> - </type> - <desc> - <p>Decodes an SSH file-binary. In the case of <c>known_hosts</c> or - <c>auth_keys</c>, the binary can include one or more lines of the - file. Returns a list of public keys and their attributes, possible - attribute values depends on the file type represented by the - binary. - </p> - + <desc> + <p>Decodes an SSH file-binary. In the case of <c>known_hosts</c> or + <c>auth_keys</c>, the binary can include one or more lines of the + file. Returns a list of public keys and their attributes, possible + attribute values depends on the file type represented by the + binary. + </p> + <p>If the <c>Type</c> is <c>ssh2_pubkey</c>, the result will be + <c>Decoded_ssh2_pubkey</c>. Otherwise it will be <c>Decoded_OtherType</c>. + </p> <taglist> <tag>RFC4716 attributes - see RFC 4716.</tag> <item><p>{headers, [{string(), utf8_string()}]}</p></item> @@ -1106,23 +910,25 @@ end <item>{comment, string()}</item> <item><p>{bits, integer()} - In SSH version 1 files.</p></item> </taglist> - + <p>Example: <c>{ok, SshBin} = file:read_file("known_hosts")</c>. + </p> + <p>If <c>Type</c> is <c>public_key</c> the binary can be either + an RFC4716 public key or an OpenSSH public key.</p> </desc> </func> <func> - <name>ssh_encode([{Key, Attributes}], Type) -> binary()</name> + <name name="ssh_encode" arity="2"/> <fsummary>Encodes a list of SSH file entries to a binary.</fsummary> - <type> - <v>Key = public_key()</v> - <v>Attributes = list()</v> - <v>Type = ssh_file()</v> - </type> - <desc> - <p>Encodes a list of SSH file entries (public keys and attributes) to a binary. Possible - attributes depend on the file type, see <seealso - marker="#ssh_decode-2"> ssh_decode/2 </seealso>.</p> - </desc> + <desc> + <p>Encodes a list of SSH file entries (public keys and attributes) to a binary. Possible + attributes depend on the file type, see + <seealso marker="#ssh_decode-2"> ssh_decode/2 </seealso>. + </p> + <p>If the <c>Type</c> is <c>ssh2_pubkey</c>, the <c>InData</c> shall be + <c>InData_ssh2_pubkey</c>. Otherwise it shall be <c>OtherInData</c>. + </p> + </desc> </func> <func> @@ -1131,8 +937,8 @@ end <name>ssh_hostkey_fingerprint([DigestType], HostKey) -> [string()]</name> <fsummary>Calculates a ssh fingerprint for a hostkey.</fsummary> <type> - <v>Key = public_key()</v> - <v>DigestType = digest_type()</v> + <v>HostKey = <seealso marker="#type-public_key">public_key()</seealso></v> + <v>DigestType = <seealso marker="#type-digest_type">digest_type()</seealso></v> </type> <desc> <p>Calculates a ssh fingerprint from a public host key as openssh does.</p> @@ -1161,29 +967,19 @@ end </func> <func> - <name>verify(Msg, DigestType, Signature, Key) -> boolean()</name> - <name>verify(Msg, DigestType, Signature, Key, Options) -> boolean()</name> + <name name="verify" arity="4"/> + <name name="verify" arity="5"/> <fsummary>Verifies a digital signature.</fsummary> - <type> - <v>Msg = binary() | {digest,binary()}</v> - <d>The <c>Msg</c> is either the binary "plain text" data - or it is the hashed value of "plain text", that is, the digest.</d> - <v>DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()</v> - <v>Signature = binary()</v> - <v>Key = rsa_public_key() | dsa_public_key() | ec_public_key()</v> - <v>Options = public_sign_options()</v> - </type> <desc> <p>Verifies a digital signature.</p> + <p>The <c>Msg</c> is either the binary "plain text" data + or it is the hashed value of "plain text", that is, the digest.</p> </desc> </func> <func> - <name>short_name_hash(Name) -> string()</name> + <name name="short_name_hash" arity="1"/> <fsummary>Generates a short hash of an issuer name.</fsummary> - <type> - <v>Name = issuer_name()</v> - </type> <desc> <p>Generates a short hash of an issuer name. The hash is returned as a string containing eight hexadecimal digits.</p> diff --git a/lib/public_key/doc/src/specs.xml b/lib/public_key/doc/src/specs.xml new file mode 100644 index 0000000000..e358ea1154 --- /dev/null +++ b/lib/public_key/doc/src/specs.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" ?> +<specs xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="../specs/specs_public_key.xml"/> +</specs> diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 3704503f1e..3f609ce6c6 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -76,7 +76,7 @@ -type dsa_private_key() :: #'DSAPrivateKey'{}. -type dsa_public_key() :: {integer(), #'Dss-Parms'{}}. -type ecpk_parameters() :: {ecParameters, #'ECParameters'{}} | {namedCurve, Oid::tuple()}. --type ecpk_parameters_api() :: ecpk_parameters() | #'ECParameters'{} | {namedCurve, Name::atom()}. +-type ecpk_parameters_api() :: ecpk_parameters() | #'ECParameters'{} | {namedCurve, Name::crypto:ec_named_curve()}. -type ec_public_key() :: {#'ECPoint'{}, ecpk_parameters_api()}. -type ec_private_key() :: #'ECPrivateKey'{}. -type key_params() :: #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{} | @@ -88,28 +88,41 @@ 'CertificationRequest' | 'CertificateList' | 'ECPrivateKey' | 'EcpkParameters'. -type pem_entry() :: {pki_asn1_type(), - binary(), %% DER or Encrypted DER - not_encrypted | {Cipher :: string(), Salt :: binary()} | - {Cipher :: string(), #'PBES2-params'{}} | - {Cipher :: string(), {#'PBEParameter'{}, atom()}} %% hash type + der_or_encrypted_der(), + not_encrypted | cipher_info() }. +-type der_or_encrypted_der() :: binary(). +-type cipher_info() :: {cipher(), + cipher_info_params()} . +-type cipher() :: string() . % "RC2-CBC" | "DES-CBC" | "DES-EDE3-CBC", +-type cipher_info_params() :: salt() + | {#'PBEParameter'{}, digest_type()} + | #'PBES2-params'{} . + +-type salt() :: binary(). % crypto:strong_rand_bytes(8) +%% -type cipher_info() :: {Cipher :: string(), Salt :: binary()} | +%% {Cipher :: string(), #'PBES2-params'{}} | +%% {Cipher :: string(), {#'PBEParameter'{}, atom()}} %% hash type +%% . + -type asn1_type() :: atom(). %% see "OTP-PUB-KEY.hrl -type ssh_file() :: openssh_public_key | rfc4716_public_key | known_hosts | auth_keys. --type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' - | 'rsa_no_padding'. --type rsa_sign_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_pss_padding'. --type public_crypt_options() :: [{rsa_pad, rsa_padding()}]. --type rsa_digest_type() :: 'md5' | 'ripemd160' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'. --type dss_digest_type() :: 'none' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'. %% None is for backwards compatibility --type ecdsa_digest_type() :: 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'. --type public_sign_options() :: [{rsa_pad, rsa_sign_padding()} | {rsa_pss_saltlen, integer()}]. --type digest_type() :: rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(). +-type digest_type() :: none % None is for backwards compatibility + | crypto:rsa_digest_type() + | crypto:dss_digest_type() + | crypto:ecdsa_digest_type(). -type crl_reason() :: unspecified | keyCompromise | cACompromise | affiliationChanged | superseded | cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise. -type oid() :: tuple(). -type chain_type() :: server_chain | client_chain. +-type issuer_id() :: {SerialNr::integer(), issuer_name()} . + +-type issuer_name() :: {rdnSequence,[#'AttributeTypeAndValue'{}]} . + + + -define(UINT32(X), X:32/unsigned-big-integer). -define(DER_NULL, <<5, 0>>). @@ -134,11 +147,11 @@ pem_encode(PemEntries) when is_list(PemEntries) -> iolist_to_binary(pubkey_pem:encode(PemEntries)). %%-------------------------------------------------------------------- --spec pem_entry_decode(pem_entry(), string()) -> term(). -% %% Description: Decodes a pem entry. pem_decode/1 returns a list of %% pem entries. %%-------------------------------------------------------------------- +-spec pem_entry_decode(PemEntry) -> term() when PemEntry :: pem_entry() . + pem_entry_decode({'SubjectPublicKeyInfo', Der, _}) -> {_, {'AlgorithmIdentifier', AlgId, Params}, Key0} = der_decode('SubjectPublicKeyInfo', Der), @@ -156,6 +169,9 @@ pem_entry_decode({'SubjectPublicKeyInfo', Der, _}) -> pem_entry_decode({Asn1Type, Der, not_encrypted}) when is_atom(Asn1Type), is_binary(Der) -> der_decode(Asn1Type, Der). + +-spec pem_entry_decode(PemEntry, Password) -> term() when PemEntry :: pem_entry(), + Password :: string() . pem_entry_decode({Asn1Type, Der, not_encrypted}, _) when is_atom(Asn1Type), is_binary(Der) -> der_decode(Asn1Type, Der); @@ -181,11 +197,12 @@ pem_entry_decode({Asn1Type, CryptDer, {Cipher, Salt}} = PemEntry, %%-------------------------------------------------------------------- --spec pem_entry_encode(pki_asn1_type(), term()) -> pem_entry(). --spec pem_entry_encode(pki_asn1_type(), term(), term()) -> pem_entry(). %% %% Description: Creates a pem entry that can be feed to pem_encode/1. %%-------------------------------------------------------------------- +-spec pem_entry_encode(Asn1Type, Entity) -> pem_entry() when Asn1Type :: pki_asn1_type(), + Entity :: term() . + pem_entry_encode('SubjectPublicKeyInfo', Entity=#'RSAPublicKey'{}) -> Der = der_encode('RSAPublicKey', Entity), Spki = {'SubjectPublicKeyInfo', @@ -208,6 +225,13 @@ pem_entry_encode('SubjectPublicKeyInfo', pem_entry_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> Der = der_encode(Asn1Type, Entity), {Asn1Type, Der, not_encrypted}. + +-spec pem_entry_encode(Asn1Type, Entity, InfoPwd) -> + pem_entry() when Asn1Type :: pki_asn1_type(), + Entity :: term(), + InfoPwd :: {CipherInfo,Password}, + CipherInfo :: cipher_info(), + Password :: string() . pem_entry_encode(Asn1Type, Entity, {{Cipher, #'PBES2-params'{}} = CipherInfo, Password}) when is_atom(Asn1Type) andalso is_list(Password) andalso @@ -229,7 +253,9 @@ pem_entry_encode(Asn1Type, Entity, {{Cipher, Salt} = CipherInfo, do_pem_entry_encode(Asn1Type, Entity, CipherInfo, Password). %%-------------------------------------------------------------------- --spec der_decode(asn1_type(), Der::binary()) -> term(). +-spec der_decode(Asn1Type, Der) -> Entity when Asn1Type :: asn1_type(), + Der :: binary(), + Entity :: term(). %% %% Description: Decodes a public key asn1 der encoded entity. %%-------------------------------------------------------------------- @@ -269,7 +295,9 @@ der_priv_key_decode(PKCS8Key) -> PKCS8Key. %%-------------------------------------------------------------------- --spec der_encode(asn1_type(), term()) -> Der::binary(). +-spec der_encode(Asn1Type, Entity) -> Der when Asn1Type :: asn1_type(), + Entity :: term(), + Der :: binary() . %% %% Description: Encodes a public key entity with asn1 DER encoding. %%-------------------------------------------------------------------- @@ -311,8 +339,10 @@ der_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> end. %%-------------------------------------------------------------------- --spec pkix_decode_cert(Cert::binary(), plain | otp) -> - #'Certificate'{} | #'OTPCertificate'{}. +-spec pkix_decode_cert(Cert, Type) -> + #'Certificate'{} | #'OTPCertificate'{} + when Cert :: der_encoded(), + Type :: plain | otp . %% %% Description: Decodes an asn1 der encoded pkix certificate. The otp %% option will use the customized asn1 specification OTP-PKIX.asn1 for @@ -332,7 +362,11 @@ pkix_decode_cert(DerCert, otp) when is_binary(DerCert) -> end. %%-------------------------------------------------------------------- --spec pkix_encode(asn1_type(), term(), otp | plain) -> Der::binary(). +-spec pkix_encode(Asn1Type, Entity, Type) -> Der + when Asn1Type :: asn1_type(), + Entity :: term(), + Type :: otp | plain, + Der :: der_encoded() . %% %% Description: Der encodes a certificate or part of a certificate. %% This function must be used for encoding certificates or parts of certificates @@ -347,16 +381,21 @@ pkix_encode(Asn1Type, Term0, otp) when is_atom(Asn1Type) -> der_encode(Asn1Type, Term). %%-------------------------------------------------------------------- --spec decrypt_private(CipherText :: binary(), rsa_private_key()) -> - PlainText :: binary(). --spec decrypt_private(CipherText :: binary(), rsa_private_key(), - public_crypt_options()) -> PlainText :: binary(). %% %% Description: Public key decryption using the private key. %%-------------------------------------------------------------------- +-spec decrypt_private(CipherText, Key) -> + PlainText when CipherText :: binary(), + Key :: rsa_private_key(), + PlainText :: binary() . decrypt_private(CipherText, Key) -> decrypt_private(CipherText, Key, []). +-spec decrypt_private(CipherText, Key, Options) -> + PlainText when CipherText :: binary(), + Key :: rsa_private_key(), + Options :: crypto:pk_encrypt_decrypt_opts(), + PlainText :: binary() . decrypt_private(CipherText, #'RSAPrivateKey'{} = Key, Options) @@ -366,61 +405,69 @@ decrypt_private(CipherText, crypto:private_decrypt(rsa, CipherText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- --spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key()) -> - PlainText :: binary(). --spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key(), - public_crypt_options()) -> PlainText :: binary(). -%% NOTE: The rsa_private_key() is not part of the documented API it is -%% here for testing purposes, in a real situation this is not a relevant -%% thing to do. -%% %% Description: Public key decryption using the public key. %%-------------------------------------------------------------------- +-spec decrypt_public(CipherText, Key) -> + PlainText + when CipherText :: binary(), + Key :: rsa_public_key(), + PlainText :: binary() . decrypt_public(CipherText, Key) -> decrypt_public(CipherText, Key, []). +-spec decrypt_public(CipherText, Key, Options) -> + PlainText + when CipherText :: binary(), + Key :: rsa_public_key(), + Options :: crypto:pk_encrypt_decrypt_opts(), + PlainText :: binary() . decrypt_public(CipherText, #'RSAPublicKey'{modulus = N, publicExponent = E}, Options) when is_binary(CipherText), is_list(Options) -> - decrypt_public(CipherText, N,E, Options); - -decrypt_public(CipherText,#'RSAPrivateKey'{modulus = N, publicExponent = E}, - Options) when is_binary(CipherText), is_list(Options) -> - decrypt_public(CipherText, N,E, Options). + Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), + crypto:public_decrypt(rsa, CipherText,[E, N], Padding). %%-------------------------------------------------------------------- --spec encrypt_public(PlainText :: binary(), rsa_public_key() | rsa_private_key()) -> - CipherText :: binary(). --spec encrypt_public(PlainText :: binary(), rsa_public_key() | rsa_private_key(), - public_crypt_options()) -> CipherText :: binary(). - -%% NOTE: The rsa_private_key() is not part of the documented API it is -%% here for testing purposes, in a real situation this is not a relevant -%% thing to do. -%% %% Description: Public key encryption using the public key. %%-------------------------------------------------------------------- +-spec encrypt_public(PlainText, Key) -> + CipherText + when PlainText :: binary(), + Key :: rsa_public_key(), + CipherText :: binary() . encrypt_public(PlainText, Key) -> encrypt_public(PlainText, Key, []). -encrypt_public(PlainText, #'RSAPublicKey'{modulus=N,publicExponent=E}, - Options) when is_binary(PlainText), is_list(Options) -> - encrypt_public(PlainText, N,E, Options); -encrypt_public(PlainText, #'RSAPrivateKey'{modulus=N,publicExponent=E}, +-spec encrypt_public(PlainText, Key, Options) -> + CipherText + when PlainText :: binary(), + Key :: rsa_public_key(), + Options :: crypto:pk_encrypt_decrypt_opts(), + CipherText :: binary() . +encrypt_public(PlainText, #'RSAPublicKey'{modulus=N,publicExponent=E}, Options) when is_binary(PlainText), is_list(Options) -> - encrypt_public(PlainText, N,E, Options). + Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), + crypto:public_encrypt(rsa, PlainText, [E,N], Padding). %%-------------------------------------------------------------------- --spec encrypt_private(PlainText :: binary(), rsa_private_key()) -> - CipherText :: binary(). --spec encrypt_private(PlainText :: binary(), rsa_private_key(), - public_crypt_options()) -> CipherText :: binary(). %% %% Description: Public key encryption using the private key. %%-------------------------------------------------------------------- +-spec encrypt_private(PlainText, Key) -> + CipherText + when PlainText :: binary(), + Key :: rsa_private_key(), + CipherText :: binary() . encrypt_private(PlainText, Key) -> encrypt_private(PlainText, Key, []). + +-spec encrypt_private(PlainText, Key, Options) -> + CipherText + when PlainText :: binary(), + Key :: rsa_private_key(), + Options :: crypto:pk_encrypt_decrypt_opts(), + CipherText :: binary() . encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N, publicExponent = E, privateExponent = D} = Key, @@ -432,22 +479,42 @@ encrypt_private(PlainText, crypto:private_encrypt(rsa, PlainText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- +%% Description: List available group sizes among the pre-computed dh groups +%%-------------------------------------------------------------------- +-spec dh_gex_group_sizes() -> [pos_integer()]. dh_gex_group_sizes() -> pubkey_ssh:dh_gex_group_sizes(). +%%-------------------------------------------------------------------- +%% Description: Select a precomputed group +%%-------------------------------------------------------------------- +-spec dh_gex_group(MinSize, SuggestedSize, MaxSize, Groups) -> + {ok,{Size,Group}} | {error,term()} + when MinSize :: pos_integer(), + SuggestedSize :: pos_integer(), + MaxSize :: pos_integer(), + Groups :: undefined | [{Size,[Group]}], + Size :: pos_integer(), + Group :: {G,P}, + G :: pos_integer(), + P :: pos_integer() . dh_gex_group(Min, N, Max, Groups) -> pubkey_ssh:dh_gex_group(Min, N, Max, Groups). %%-------------------------------------------------------------------- --spec generate_key(#'DHParameter'{}) -> - {Public::binary(), Private::binary()}; - (ecpk_parameters_api()) -> - #'ECPrivateKey'{}; - ({rsa, Size::pos_integer(), PubExp::pos_integer()}) -> - #'RSAPrivateKey'{}. - -%% Description: Generates a new keypair +%% Description: Generate a new key pair %%-------------------------------------------------------------------- +-spec generate_key(DHparams | ECparams | RSAparams) -> + DHkeys | ECkey | RSAkey + when DHparams :: #'DHParameter'{}, + DHkeys :: {PublicDH::binary(), PrivateDH::binary()}, + ECparams :: ecpk_parameters_api(), + ECkey :: #'ECPrivateKey'{}, + RSAparams :: {rsa, Size, PubExp}, + Size::pos_integer(), + PubExp::pos_integer(), + RSAkey :: #'RSAPrivateKey'{} . + generate_key(#'DHParameter'{prime = P, base = G}) -> crypto:generate_key(dh, [P, G]); generate_key({namedCurve, _} = Params) -> @@ -494,24 +561,34 @@ generate_key({rsa, ModulusSize, PublicExponent}) -> end. %%-------------------------------------------------------------------- --spec compute_key(#'ECPoint'{} , #'ECPrivateKey'{}) -> binary(). --spec compute_key(OthersKey ::binary(), MyKey::binary(), #'DHParameter'{}) -> binary(). %% Description: Compute shared secret %%-------------------------------------------------------------------- +-spec compute_key(OthersECDHkey, MyECDHkey) -> + SharedSecret + when OthersECDHkey :: #'ECPoint'{}, + MyECDHkey :: #'ECPrivateKey'{}, + SharedSecret :: binary(). compute_key(#'ECPoint'{point = Point}, #'ECPrivateKey'{privateKey = PrivKey, parameters = Param}) -> ECCurve = ec_curve_spec(Param), crypto:compute_key(ecdh, Point, PrivKey, ECCurve). +-spec compute_key(OthersDHkey, MyDHkey, DHparms) -> + SharedSecret + when OthersDHkey :: crypto:dh_public(), % Was: binary(), + MyDHkey :: crypto:dh_private(), % Was: binary(), + DHparms :: #'DHParameter'{}, + SharedSecret :: binary(). compute_key(PubKey, PrivKey, #'DHParameter'{prime = P, base = G}) -> crypto:compute_key(dh, PubKey, PrivKey, [P, G]). %%-------------------------------------------------------------------- --spec pkix_sign_types(SignatureAlg::oid()) -> - %% Relevant dsa digest type is subpart of rsa digest type - { DigestType :: rsa_digest_type(), - SignatureType :: rsa | dsa | ecdsa - }. +-spec pkix_sign_types(AlgorithmId) -> + {DigestType, SignatureType} + when AlgorithmId :: oid(), + %% Relevant dsa digest type is a subset of rsa_digest_type() + DigestType :: crypto:rsa_digest_type(), + SignatureType :: rsa | dsa | ecdsa . %% Description: %%-------------------------------------------------------------------- pkix_sign_types(?sha1WithRSAEncryption) -> @@ -542,24 +619,24 @@ pkix_sign_types(?'ecdsa-with-SHA512') -> {sha512, ecdsa}. %%-------------------------------------------------------------------- --spec sign(binary() | {digest, binary()}, - rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), - rsa_private_key() | dsa_private_key() | ec_private_key() - ) -> Signature :: binary(). - --spec sign(binary() | {digest, binary()}, - rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), - rsa_private_key() | dsa_private_key() | ec_private_key(), - public_sign_options() - ) -> Signature :: binary(). - %% Description: Create digital signature. %%-------------------------------------------------------------------- +-spec sign(Msg, DigestType, Key) -> + Signature when Msg :: binary() | {digest,binary()}, + DigestType :: digest_type(), + Key :: private_key(), + Signature :: binary() . sign(DigestOrPlainText, DigestType, Key) -> sign(DigestOrPlainText, DigestType, Key, []). -%% Backwards compatible +-spec sign(Msg, DigestType, Key, Options) -> + Signature when Msg :: binary() | {digest,binary()}, + DigestType :: digest_type(), + Key :: private_key(), + Options :: crypto:pk_sign_verify_opts(), + Signature :: binary() . sign(Digest, none, Key = #'DSAPrivateKey'{}, Options) when is_binary(Digest) -> + %% Backwards compatible sign({digest, Digest}, sha, Key, Options); sign(DigestOrPlainText, DigestType, Key, Options) -> case format_sign_key(Key) of @@ -570,28 +647,26 @@ sign(DigestOrPlainText, DigestType, Key, Options) -> end. %%-------------------------------------------------------------------- --spec verify(binary() | {digest, binary()}, - rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), - Signature :: binary(), - rsa_public_key() | dsa_public_key() | ec_public_key() - | rsa_private_key() | dsa_private_key() | ec_private_key() - ) -> boolean(). - --spec verify(binary() | {digest, binary()}, - rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), - Signature :: binary(), - rsa_public_key() | dsa_public_key() | ec_public_key() - | rsa_private_key() | dsa_private_key() | ec_private_key(), - public_sign_options() - ) -> boolean(). - %% Description: Verifies a digital signature. %%-------------------------------------------------------------------- +-spec verify(Msg, DigestType, Signature, Key) -> + boolean() when Msg :: binary() | {digest, binary()}, + DigestType :: digest_type(), + Signature :: binary(), + Key :: public_key() . + verify(DigestOrPlainText, DigestType, Signature, Key) -> verify(DigestOrPlainText, DigestType, Signature, Key, []). -%% Backwards compatible +-spec verify(Msg, DigestType, Signature, Key, Options) -> + boolean() when Msg :: binary() | {digest, binary()}, + DigestType :: digest_type(), + Signature :: binary(), + Key :: public_key(), + Options :: crypto:pk_sign_verify_opts(). + verify(Digest, none, Signature, Key = {_, #'Dss-Parms'{}}, Options) when is_binary(Digest) -> + %% Backwards compatible verify({digest, Digest}, sha, Signature, Key, Options); verify(DigestOrPlainText, DigestType, Signature, Key, Options) when is_binary(Signature) -> case format_verify_key(Key) of @@ -606,8 +681,8 @@ verify(_,_,_,_,_) -> false. %%-------------------------------------------------------------------- --spec pkix_dist_point(der_encoded() | #'OTPCertificate'{}) -> - #'DistributionPoint'{}. +-spec pkix_dist_point(Cert) -> DistPoint when Cert :: der_encoded() | #'OTPCertificate'{}, + DistPoint :: #'DistributionPoint'{}. %% Description: Creates a distribution point for CRLs issued by the same issuer as <c>Cert</c>. %%-------------------------------------------------------------------- pkix_dist_point(OtpCert) when is_binary(OtpCert) -> @@ -630,8 +705,8 @@ pkix_dist_point(OtpCert) -> reasons = asn1_NOVALUE, distributionPoint = Point}. %%-------------------------------------------------------------------- --spec pkix_dist_points(der_encoded() | #'OTPCertificate'{}) -> - [#'DistributionPoint'{}]. +-spec pkix_dist_points(Cert) -> DistPoints when Cert :: der_encoded() | #'OTPCertificate'{}, + DistPoints :: [ #'DistributionPoint'{} ]. %% Description: Extracts distributionpoints specified in the certificates extensions. %%-------------------------------------------------------------------- pkix_dist_points(OtpCert) when is_binary(OtpCert) -> @@ -645,8 +720,10 @@ pkix_dist_points(OtpCert) -> [], Value). %%-------------------------------------------------------------------- --spec pkix_match_dist_point(der_encoded() | #'CertificateList'{}, - #'DistributionPoint'{}) -> boolean(). +-spec pkix_match_dist_point(CRL, DistPoint) -> + boolean() + when CRL :: der_encoded() | #'CertificateList'{}, + DistPoint :: #'DistributionPoint'{}. %% Description: Check whether the given distribution point matches %% the "issuing distribution point" of the CRL. %%-------------------------------------------------------------------- @@ -677,8 +754,9 @@ pkix_match_dist_point(#'CertificateList'{ end. %%-------------------------------------------------------------------- --spec pkix_sign(#'OTPTBSCertificate'{}, - rsa_private_key() | dsa_private_key() | ec_private_key()) -> Der::binary(). +-spec pkix_sign(Cert, Key) -> Der when Cert :: #'OTPTBSCertificate'{}, + Key :: private_key(), + Der :: der_encoded() . %% %% Description: Sign a pkix x.509 certificate. Returns the corresponding %% der encoded 'Certificate'{} @@ -697,8 +775,8 @@ pkix_sign(#'OTPTBSCertificate'{signature = pkix_encode('OTPCertificate', Cert, otp). %%-------------------------------------------------------------------- --spec pkix_verify(Cert::binary(), rsa_public_key()| - dsa_public_key() | ec_public_key()) -> boolean(). +-spec pkix_verify(Cert, Key) -> boolean() when Cert :: der_encoded(), + Key :: public_key() . %% %% Description: Verify pkix x.509 certificate signature. %%-------------------------------------------------------------------- @@ -718,7 +796,9 @@ pkix_verify(DerCert, Key = {#'ECPoint'{}, _}) verify(PlainText, DigestType, Signature, Key). %%-------------------------------------------------------------------- --spec pkix_crl_verify(CRL::binary() | #'CertificateList'{}, Cert::binary() | #'OTPCertificate'{}) -> boolean(). +-spec pkix_crl_verify(CRL, Cert) -> boolean() + when CRL :: der_encoded() | #'CertificateList'{}, + Cert :: der_encoded() | #'OTPCertificate'{} . %% %% Description: Verify that Cert is the CRL signer. %%-------------------------------------------------------------------- @@ -737,9 +817,12 @@ pkix_crl_verify(#'CertificateList'{} = CRL, #'OTPCertificate'{} = Cert) -> PublicKey, PublicKeyParams). %%-------------------------------------------------------------------- --spec pkix_is_issuer(Cert :: der_encoded()| #'OTPCertificate'{} | #'CertificateList'{}, - IssuerCert :: der_encoded()| - #'OTPCertificate'{}) -> boolean(). +-spec pkix_is_issuer(Cert, IssuerCert) -> + boolean() when Cert :: der_encoded() + | #'OTPCertificate'{} + | #'CertificateList'{}, + IssuerCert :: der_encoded() + | #'OTPCertificate'{} . %% %% Description: Checks if <IssuerCert> issued <Cert>. %%-------------------------------------------------------------------- @@ -759,7 +842,7 @@ pkix_is_issuer(#'CertificateList'{tbsCertList = TBSCRL}, pubkey_cert_records:transform(TBSCRL#'TBSCertList'.issuer, decode)). %%-------------------------------------------------------------------- --spec pkix_is_self_signed(Cert::binary()| #'OTPCertificate'{}) -> boolean(). +-spec pkix_is_self_signed(Cert) -> boolean() when Cert::der_encoded()| #'OTPCertificate'{}. %% %% Description: Checks if a Certificate is self signed. %%-------------------------------------------------------------------- @@ -770,7 +853,7 @@ pkix_is_self_signed(Cert) when is_binary(Cert) -> pkix_is_self_signed(OtpCert). %%-------------------------------------------------------------------- --spec pkix_is_fixed_dh_cert(Cert::binary()| #'OTPCertificate'{}) -> boolean(). +-spec pkix_is_fixed_dh_cert(Cert) -> boolean() when Cert::der_encoded()| #'OTPCertificate'{}. %% %% Description: Checks if a Certificate is a fixed Diffie-Hellman Cert. %%-------------------------------------------------------------------- @@ -781,13 +864,12 @@ pkix_is_fixed_dh_cert(Cert) when is_binary(Cert) -> pkix_is_fixed_dh_cert(OtpCert). %%-------------------------------------------------------------------- --spec pkix_issuer_id(Cert::binary()| #'OTPCertificate'{}, - IssuedBy :: self | other) -> - {ok, {SerialNr :: integer(), - Issuer :: {rdnSequence, - [#'AttributeTypeAndValue'{}]}}} - | {error, Reason :: term()}. -% +-spec pkix_issuer_id(Cert, IssuedBy) -> + {ok, issuer_id()} | {error, Reason} + when Cert::der_encoded()| #'OTPCertificate'{}, + IssuedBy :: self | other, + Reason :: term() . + %% Description: Returns the issuer id. %%-------------------------------------------------------------------- pkix_issuer_id(#'OTPCertificate'{} = OtpCert, Signed) when (Signed == self) or @@ -798,9 +880,9 @@ pkix_issuer_id(Cert, Signed) when is_binary(Cert) -> pkix_issuer_id(OtpCert, Signed). %%-------------------------------------------------------------------- --spec pkix_crl_issuer(CRL::binary()| #'CertificateList'{}) -> - {rdnSequence, - [#'AttributeTypeAndValue'{}]}. +-spec pkix_crl_issuer(CRL| #'CertificateList'{}) -> + Issuer when CRL :: der_encoded(), + Issuer :: issuer_name() . % %% Description: Returns the issuer. %%-------------------------------------------------------------------- @@ -811,10 +893,9 @@ pkix_crl_issuer(#'CertificateList'{} = CRL) -> CRL#'CertificateList'.tbsCertList#'TBSCertList'.issuer, decode). %%-------------------------------------------------------------------- --spec pkix_normalize_name({rdnSequence, - [#'AttributeTypeAndValue'{}]}) -> - {rdnSequence, - [#'AttributeTypeAndValue'{}]}. +-spec pkix_normalize_name(Issuer) -> Normalized + when Issuer :: issuer_name(), + Normalized :: issuer_name() . %% %% Description: Normalizes a issuer name so that it can be easily %% compared to another issuer name. @@ -825,7 +906,7 @@ pkix_normalize_name(Issuer) -> %%-------------------------------------------------------------------- -spec pkix_path_validation(Cert::binary()| #'OTPCertificate'{} | atom(), CertChain :: [binary()] , - Options :: proplists:proplist()) -> + Options :: [{atom(),term()}]) -> {ok, {PublicKeyInfo :: term(), PolicyTree :: term()}} | {error, {bad_cert, Reason :: term()}}. @@ -861,11 +942,19 @@ pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options) path_validation(CertChain, ValidationState). %-------------------------------------------------------------------- --spec pkix_crls_validate(#'OTPCertificate'{}, - [{DP::#'DistributionPoint'{}, {DerCRL::binary(), CRL::#'CertificateList'{}}}], - Options :: proplists:proplist()) -> valid | {bad_cert, revocation_status_undetermined} | - {bad_cert, {revocation_status_undetermined, Reason::term()}} | - {bad_cert, {revoked, crl_reason()}}. +-spec pkix_crls_validate(OTPcertificate, DPandCRLs, Options) -> + CRLstatus when OTPcertificate :: #'OTPCertificate'{}, + DPandCRLs :: [DPandCRL], + DPandCRL :: {DP, {DerCRL, CRL}}, + DP :: #'DistributionPoint'{}, + DerCRL :: der_encoded(), + CRL :: #'CertificateList'{}, + Options :: [{atom(),term()}], + CRLstatus :: valid + | {bad_cert, BadCertReason}, + BadCertReason :: revocation_status_undetermined + | {revocation_status_undetermined, Reason::term()} + | {revoked, crl_reason()}. %% Description: Performs a CRL validation according to RFC 5280. %%-------------------------------------------------------------------- @@ -882,20 +971,10 @@ pkix_crls_validate(OtpCert, DPAndCRLs0, Options) -> Options, pubkey_crl:init_revokation_state()). %-------------------------------------------------------------------- --spec pkix_verify_hostname(#'OTPCertificate'{} | binary(), - referenceIDs() - ) -> boolean(). - --spec pkix_verify_hostname(#'OTPCertificate'{} | binary(), - referenceIDs(), - proplists:proplist()) -> boolean(). - -type referenceIDs() :: [referenceID()] . -type referenceID() :: {uri_id | dns_id | ip | srv_id | oid(), string()} | {ip, inet:ip_address()} . --spec pkix_verify_hostname_match_fun(high_level_alg()) -> match_fun() . - -type high_level_alg() :: https . -type match_fun() :: fun((ReferenceID::referenceID() | string(), PresentedID::{atom()|oid(),string()}) -> match_fun_result() ) . @@ -903,9 +982,20 @@ pkix_crls_validate(OtpCert, DPAndCRLs0, Options) -> %% Description: Validates a hostname to RFC 6125 %%-------------------------------------------------------------------- +-spec pkix_verify_hostname(Cert, ReferenceIDs) -> boolean() + when Cert :: der_encoded() + | #'OTPCertificate'{}, + ReferenceIDs :: referenceIDs() . pkix_verify_hostname(Cert, ReferenceIDs) -> pkix_verify_hostname(Cert, ReferenceIDs, []). +-spec pkix_verify_hostname(Cert, ReferenceIDs, Options) -> + boolean() + when Cert :: der_encoded() + | #'OTPCertificate'{}, + ReferenceIDs :: referenceIDs(), + Options :: [{atom(),term()}] . + pkix_verify_hostname(BinCert, ReferenceIDs, Options) when is_binary(BinCert) -> pkix_verify_hostname(pkix_decode_cert(BinCert,otp), ReferenceIDs, Options); @@ -964,15 +1054,25 @@ pkix_verify_hostname(Cert = #'OTPCertificate'{tbsCertificate = TbsCert}, Referen end end. + +-spec pkix_verify_hostname_match_fun(high_level_alg()) -> match_fun() . + pkix_verify_hostname_match_fun(https) -> fun({dns_id,FQDN=[_|_]}, {dNSName,Name=[_|_]}) -> verify_hostname_match_wildcard(FQDN, Name); (_, _) -> default end. %%-------------------------------------------------------------------- --spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}] - ; (binary(), ssh2_pubkey) -> public_key() - . +-spec ssh_decode(SshBin, Type) -> + Decoded + when SshBin :: binary(), + Type :: ssh2_pubkey | OtherType, + OtherType :: public_key | ssh_file(), + Decoded :: Decoded_ssh2_pubkey + | Decoded_OtherType, + Decoded_ssh2_pubkey :: public_key(), + Decoded_OtherType :: [{public_key(), Attributes}], + Attributes :: [{atom(),term()}] . %% %% Description: Decodes a ssh file-binary. In the case of know_hosts %% or auth_keys the binary may include one or more lines of the @@ -990,9 +1090,15 @@ ssh_decode(SshBin, Type) when is_binary(SshBin), pubkey_ssh:decode(SshBin, Type). %%-------------------------------------------------------------------- --spec ssh_encode([{public_key(), Attributes::list()}], ssh_file()) -> binary() - ; (public_key(), ssh2_pubkey) -> binary() - . +-spec ssh_encode(InData, Type) -> + binary() + when Type :: ssh2_pubkey | OtherType, + OtherType :: public_key | ssh_file(), + InData :: InData_ssh2_pubkey | OtherInData, + InData_ssh2_pubkey :: public_key(), + OtherInData :: [{Key,Attributes}], + Key :: public_key(), + Attributes :: [{atom(),term()}] . %% %% Description: Encodes a list of ssh file entries (public keys and %% attributes) to a binary. Possible attributes depends on the file @@ -1027,13 +1133,14 @@ oid2ssh_curvename(?'secp521r1') -> <<"nistp521">>. %%-------------------------------------------------------------------- -spec ssh_hostkey_fingerprint(public_key()) -> string(). --spec ssh_hostkey_fingerprint( digest_type(), public_key()) -> string() - ; ([digest_type()], public_key()) -> [string()] - . ssh_hostkey_fingerprint(Key) -> sshfp_string(md5, public_key:ssh_encode(Key,ssh2_pubkey) ). + +-spec ssh_hostkey_fingerprint( digest_type(), public_key()) -> string() + ; ([digest_type()], public_key()) -> [string()] + . ssh_hostkey_fingerprint(HashAlgs, Key) when is_list(HashAlgs) -> EncKey = public_key:ssh_encode(Key, ssh2_pubkey), [sshfp_full_string(HashAlg,EncKey) || HashAlg <- HashAlgs]; @@ -1071,8 +1178,7 @@ fp_fmt(b64, Bin) -> [lists:nth(C+1,B64Chars) || <<C:6>> <= <<Bin/binary,0:Padding>> ]. %%-------------------------------------------------------------------- --spec short_name_hash({rdnSequence, [#'AttributeTypeAndValue'{}]}) -> - string(). +-spec short_name_hash(Name) -> string() when Name :: issuer_name() . %% Description: Generates OpenSSL-style hash of a name. %%-------------------------------------------------------------------- @@ -1103,10 +1209,11 @@ pkix_test_data(#{} = Chain) -> pubkey_cert:gen_test_certs(maps:merge(Default, Chain)). %%-------------------------------------------------------------------- --spec pkix_test_root_cert( - Name :: string(), Opts :: [pubkey_cert:cert_opt()]) -> - pubkey_cert:test_root_cert(). - +-spec pkix_test_root_cert(Name, Options) -> + RootCert + when Name :: string(), + Options :: [{atom(),term()}], %[cert_opt()], + RootCert :: pubkey_cert:test_root_cert(). %% Description: Generates a root cert suitable for pkix_test_data/1 %%-------------------------------------------------------------------- @@ -1152,14 +1259,6 @@ do_pem_entry_decode({Asn1Type,_, _} = PemEntry, Password) -> Der = pubkey_pem:decipher(PemEntry, Password), der_decode(Asn1Type, Der). -encrypt_public(PlainText, N, E, Options)-> - Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:public_encrypt(rsa, PlainText, [E,N], Padding). - -decrypt_public(CipherText, N,E, Options) -> - Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:public_decrypt(rsa, CipherText,[E, N], Padding). - path_validation([], #path_validation_state{working_public_key_algorithm = Algorithm, working_public_key = diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index cfd8e7a34b..1955e9e119 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -718,12 +718,8 @@ encrypt_decrypt(Config) when is_list(Config) -> Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")), RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey), Msg = public_key:decrypt_public(RsaEncrypted, PublicKey), - Msg = public_key:decrypt_public(RsaEncrypted, PrivateKey), RsaEncrypted2 = public_key:encrypt_public(Msg, PublicKey), - RsaEncrypted3 = public_key:encrypt_public(Msg, PrivateKey), Msg = public_key:decrypt_private(RsaEncrypted2, PrivateKey), - Msg = public_key:decrypt_private(RsaEncrypted3, PrivateKey), - ok. %%-------------------------------------------------------------------- |