From 709d0482af92ca52d26296f008b495a36161ca00 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Tue, 14 Aug 2012 16:53:00 +0200 Subject: PUBLIC_KEY: add support for Elliptic Curves to public_key app --- lib/public_key/asn1/ECPrivateKey.asn1 | 24 ++++++ lib/public_key/asn1/OTP-PKIX.asn1 | 42 +++++++++- lib/public_key/asn1/OTP-PUB-KEY.set.asn | 1 + lib/public_key/asn1/PKCS-1.asn1 | 32 ++++++++ lib/public_key/asn1/PKIX1Algorithms88.asn1 | 118 ++++++++++++++++++++--------- lib/public_key/doc/src/public_key.xml | 15 ++-- lib/public_key/include/public_key.hrl | 4 + lib/public_key/src/pubkey_cert_records.erl | 88 ++++++++++++++++++++- lib/public_key/src/pubkey_pem.erl | 16 +++- lib/public_key/src/public_key.erl | 90 +++++++++++++++++++++- lib/public_key/test/erl_make_certs.erl | 67 ++++++++++++++-- 11 files changed, 441 insertions(+), 56 deletions(-) create mode 100644 lib/public_key/asn1/ECPrivateKey.asn1 (limited to 'lib/public_key') diff --git a/lib/public_key/asn1/ECPrivateKey.asn1 b/lib/public_key/asn1/ECPrivateKey.asn1 new file mode 100644 index 0000000000..e8607c4f7b --- /dev/null +++ b/lib/public_key/asn1/ECPrivateKey.asn1 @@ -0,0 +1,24 @@ +ECPrivateKey { iso(1) identified-organization(3) dod(6) + internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) + id-mod-ecprivateKey(65) } + +DEFINITIONS EXPLICIT TAGS ::= + +BEGIN + +-- EXPORTS ALL; + +IMPORTS + +-- FROM New PKIX ASN.1 [RFC5912] + +OTPEcpkParameters FROM OTP-PKIX; + +ECPrivateKey ::= SEQUENCE { + version INTEGER, + privateKey OCTET STRING, + parameters [0] OTPEcpkParameters OPTIONAL, + publicKey [1] BIT STRING OPTIONAL +} + +END \ No newline at end of file diff --git a/lib/public_key/asn1/OTP-PKIX.asn1 b/lib/public_key/asn1/OTP-PKIX.asn1 index a90fe2840c..4a9d401345 100644 --- a/lib/public_key/asn1/OTP-PKIX.asn1 +++ b/lib/public_key/asn1/OTP-PKIX.asn1 @@ -105,7 +105,8 @@ IMPORTS rsaEncryption, RSAPublicKey, dhpublicnumber, DomainParameters, DHPublicKey, id-keyExchangeAlgorithm, KEA-Parms-Id, --KEA-PublicKey, - ecdsa-with-SHA1, + ecdsa-with-SHA1, ecdsa-with-SHA224, + ecdsa-with-SHA256, ecdsa-with-SHA384, ecdsa-with-SHA512, prime-field, Prime-p, characteristic-two-field, --Characteristic-two, gnBasis, @@ -321,7 +322,11 @@ SupportedSignatureAlgorithms SIGNATURE-ALGORITHM-CLASS ::= { sha256-with-rsa-encryption | sha384-with-rsa-encryption | sha512-with-rsa-encryption | - ecdsa-with-sha1 } + ecdsa-with-sha1 | + ecdsa-with-sha224 | + ecdsa-with-sha256 | + ecdsa-with-sha384 | + ecdsa-with-sha512 } SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { dsa | rsa-encryption | dh | kea | ec-public-key } @@ -439,6 +444,22 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { ID ecdsa-with-SHA1 TYPE NULL } -- XXX Must be empty and not NULL + ecdsa-with-sha224 SIGNATURE-ALGORITHM-CLASS ::= { + ID ecdsa-with-SHA224 + TYPE NULL } -- XXX Must be empty and not NULL + + ecdsa-with-sha256 SIGNATURE-ALGORITHM-CLASS ::= { + ID ecdsa-with-SHA256 + TYPE NULL } -- XXX Must be empty and not NULL + + ecdsa-with-sha384 SIGNATURE-ALGORITHM-CLASS ::= { + ID ecdsa-with-SHA384 + TYPE NULL } -- XXX Must be empty and not NULL + + ecdsa-with-sha512 SIGNATURE-ALGORITHM-CLASS ::= { + ID ecdsa-with-SHA512 + TYPE NULL } -- XXX Must be empty and not NULL + FIELD-ID-CLASS ::= CLASS { &id OBJECT IDENTIFIER UNIQUE, &Type } @@ -489,6 +510,23 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { ID ppBasis TYPE Pentanomial } + -- Elliptic Curve parameters may be specified explicitly, + -- specified implicitly through a "named curve", or + -- inherited from the CA + + OTPEcpkParameters ::= CHOICE { + ecParameters OTPECParameters, + namedCurve OBJECT IDENTIFIER, + implicitlyCA NULL } + + OTPECParameters ::= SEQUENCE { -- Elliptic curve parameters + version ECPVer, + fieldID OTPFieldID, + curve Curve, + base ECPoint, -- Base point G + order INTEGER, -- Order n of the base point + cofactor INTEGER OPTIONAL } -- The integer h = #E(Fq)/n + -- SubjectPublicKeyInfo.algorithm ec-public-key PUBLIC-KEY-ALGORITHM-CLASS ::= { diff --git a/lib/public_key/asn1/OTP-PUB-KEY.set.asn b/lib/public_key/asn1/OTP-PUB-KEY.set.asn index f8fb318c93..e94f428e4b 100644 --- a/lib/public_key/asn1/OTP-PUB-KEY.set.asn +++ b/lib/public_key/asn1/OTP-PUB-KEY.set.asn @@ -6,5 +6,6 @@ PKIX1Algorithms88.asn1 PKCS-1.asn1 PKCS-3.asn1 DSS.asn1 +ECPrivateKey.asn1 PKCS-7.asn1 PKCS-10.asn1 diff --git a/lib/public_key/asn1/PKCS-1.asn1 b/lib/public_key/asn1/PKCS-1.asn1 index b5754790e7..117eacd8ad 100644 --- a/lib/public_key/asn1/PKCS-1.asn1 +++ b/lib/public_key/asn1/PKCS-1.asn1 @@ -52,8 +52,40 @@ id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } +id-hmacWithSHA224 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 +} + +id-hmacWithSHA256 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 +} + +id-hmacWithSHA384 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 +} + +id-hmacWithSHA512 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 +} + id-mgf1 OBJECT IDENTIFIER ::= { pkcs-1 8 } +id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) + country(16) us(840) organization(1) gov(101) csor(3) + nistalgorithm(4) hashalgs(2) 4 } + +id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) + country(16) us(840) organization(1) gov(101) csor(3) + nistalgorithm(4) hashalgs(2) 1 } + +id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) + country(16) us(840) organization(1) gov(101) csor(3) + nistalgorithm(4) hashalgs(2) 2 } + +id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) + country(16) us(840) organization(1) gov(101) csor(3) + nistalgorithm(4) hashalgs(2) 3 } + RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n diff --git a/lib/public_key/asn1/PKIX1Algorithms88.asn1 b/lib/public_key/asn1/PKIX1Algorithms88.asn1 index 74225747d3..6cc6745af6 100644 --- a/lib/public_key/asn1/PKIX1Algorithms88.asn1 +++ b/lib/public_key/asn1/PKIX1Algorithms88.asn1 @@ -98,6 +98,11 @@ -- OID for ECDSA signatures with SHA-1 ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 } + ecdsa-with-SHA2 OBJECT IDENTIFIER ::= { id-ecSigType 3 } + ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { ecdsa-with-SHA2 1 } + ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { ecdsa-with-SHA2 2 } + ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { ecdsa-with-SHA2 3 } + ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { ecdsa-with-SHA2 4 } -- OID for an elliptic curve signature -- format for the value of an ECDSA signature value @@ -199,40 +204,83 @@ -- Named Elliptic Curves in ANSI X9.62. - ellipticCurve OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) } - - c-TwoCurve OBJECT IDENTIFIER ::= { - ellipticCurve characteristicTwo(0) } - - c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 } - c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 } - c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 } - c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 } - c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 } - c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 } - c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 } - c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 } - c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 } - c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 } - c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 } - c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 } - c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 } - c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 } - c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 } - c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 } - c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 } - c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 } - c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 } - c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 } - - primeCurve OBJECT IDENTIFIER ::= { ellipticCurve prime(1) } - - prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 } - prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 } - prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 } - prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 } - prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 } - prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 } - prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 } + -- ellipticCurve OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) } + + -- c-TwoCurve OBJECT IDENTIFIER ::= { + -- ansi-ellipticCurve characteristicTwo(0) } + + -- c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 } + -- c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 } + -- c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 } + -- c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 } + -- c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 } + -- c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 } + -- c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 } + -- c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 } + -- c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 } + -- c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 } + -- c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 } + -- c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 } + -- c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 } + -- c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 } + -- c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 } + -- c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 } + -- c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 } + -- c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 } + -- c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 } + -- c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 } + + -- primeCurve OBJECT IDENTIFIER ::= { ansi-ellipticCurve prime(1) } + + -- prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 } + -- prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 } + -- prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 } + -- prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 } + -- prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 } + -- prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 } + -- prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 } + + certicom-arc OBJECT IDENTIFIER ::= { + iso(1) identified-organization(3) certicom(132) + } + + ellipticCurve OBJECT IDENTIFIER ::= { + iso(1) identified-organization(3) certicom(132) curve(0) + } + + secp192r1 OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) prime(1) 1 } + secp256r1 OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) prime(1) 7 } + + sect163k1 OBJECT IDENTIFIER ::= { ellipticCurve 1 } + sect163r1 OBJECT IDENTIFIER ::= { ellipticCurve 2 } + sect239k1 OBJECT IDENTIFIER ::= { ellipticCurve 3 } + sect113r1 OBJECT IDENTIFIER ::= { ellipticCurve 4 } + sect113r2 OBJECT IDENTIFIER ::= { ellipticCurve 5 } + secp112r1 OBJECT IDENTIFIER ::= { ellipticCurve 6 } + secp112r2 OBJECT IDENTIFIER ::= { ellipticCurve 7 } + secp160r1 OBJECT IDENTIFIER ::= { ellipticCurve 8 } + secp160k1 OBJECT IDENTIFIER ::= { ellipticCurve 9 } + secp256k1 OBJECT IDENTIFIER ::= { ellipticCurve 10 } + sect163r2 OBJECT IDENTIFIER ::= { ellipticCurve 15 } + sect283k1 OBJECT IDENTIFIER ::= { ellipticCurve 16 } + sect283r1 OBJECT IDENTIFIER ::= { ellipticCurve 17 } + sect131r1 OBJECT IDENTIFIER ::= { ellipticCurve 22 } + sect131r2 OBJECT IDENTIFIER ::= { ellipticCurve 23 } + sect193r1 OBJECT IDENTIFIER ::= { ellipticCurve 24 } + sect193r2 OBJECT IDENTIFIER ::= { ellipticCurve 25 } + sect233k1 OBJECT IDENTIFIER ::= { ellipticCurve 26 } + sect233r1 OBJECT IDENTIFIER ::= { ellipticCurve 27 } + secp128r1 OBJECT IDENTIFIER ::= { ellipticCurve 28 } + secp128r2 OBJECT IDENTIFIER ::= { ellipticCurve 29 } + secp160r2 OBJECT IDENTIFIER ::= { ellipticCurve 30 } + secp192k1 OBJECT IDENTIFIER ::= { ellipticCurve 31 } + secp224k1 OBJECT IDENTIFIER ::= { ellipticCurve 32 } + secp224r1 OBJECT IDENTIFIER ::= { ellipticCurve 33 } + secp384r1 OBJECT IDENTIFIER ::= { ellipticCurve 34 } + secp521r1 OBJECT IDENTIFIER ::= { ellipticCurve 35 } + sect409k1 OBJECT IDENTIFIER ::= { ellipticCurve 36 } + sect409r1 OBJECT IDENTIFIER ::= { ellipticCurve 37 } + sect571k1 OBJECT IDENTIFIER ::= { ellipticCurve 38 } + sect571r1 OBJECT IDENTIFIER ::= { ellipticCurve 39 } END diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index 84300f6e65..9cad17e4c3 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -84,7 +84,8 @@

pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey' | 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' | 'SubjectPublicKeyInfo' | - 'PrivateKeyInfo' | 'CertificationRequest'

+ 'PrivateKeyInfo' | 'CertificationRequest' | 'ECPrivateKey'| + 'OTPEcpkParameters'

pem_entry () = {pki_asn1_type(), binary(), %% DER or encrypted DER not_encrypted | cipher_info()}

@@ -100,6 +101,8 @@

dsa_private_key() = #'DSAPrivateKey'{}

+

ec_key() = {'ECKey', Key}

+

public_crypt_options() = [{rsa_pad, rsa_padding()}].

rsa_padding() = 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' @@ -109,6 +112,8 @@

dss_digest_type() = 'sha'

+

ecdsa_digest_type() = 'sha'

+

crl_reason() = unspecified | keyCompromise | cACompromise | affiliationChanged | superseded | cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise

@@ -528,8 +533,8 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} | The msg is either the binary "plain text" data to be signed or it is the hashed value of "plain text" i.e. the digest. - DigestType = rsa_digest_type() | dss_digest_type() - Key = rsa_private_key() | dsa_private_key() + DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() + Key = rsa_private_key() | dsa_private_key() | ec_key()

Creates a digital signature.

@@ -592,9 +597,9 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} | Msg = binary() | {digest,binary()} The msg is either the binary "plain text" data or it is the hashed value of "plain text" i.e. the digest. - DigestType = rsa_digest_type() | dss_digest_type() + DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() Signature = binary() - Key = rsa_public_key() | dsa_public_key() + Key = rsa_public_key() | dsa_public_key() | ec_key()

Verifies a digital signature

diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl index 4d1d510f29..976104fe6c 100644 --- a/lib/public_key/include/public_key.hrl +++ b/lib/public_key/include/public_key.hrl @@ -72,6 +72,10 @@ valid_ext }). +-record('ECPoint', { + point + }). + -define(unspecified, 0). -define(keyCompromise, 1). diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl index 98004c71a3..0449129809 100644 --- a/lib/public_key/src/pubkey_cert_records.erl +++ b/lib/public_key/src/pubkey_cert_records.erl @@ -23,7 +23,8 @@ -include("public_key.hrl"). --export([decode_cert/1, transform/2, supportedPublicKeyAlgorithms/1]). +-export([decode_cert/1, transform/2, supportedPublicKeyAlgorithms/1, + supportedCurvesTypes/1, namedCurves/1]). %%==================================================================== %% Internal application API @@ -101,6 +102,77 @@ supportedPublicKeyAlgorithms(?'dhpublicnumber') -> 'DHPublicKey'; supportedPublicKeyAlgorithms(?'id-keyExchangeAlgorithm') -> 'KEA-PublicKey'; supportedPublicKeyAlgorithms(?'id-ecPublicKey') -> 'ECPoint'. +supportedCurvesTypes(?'characteristic-two-field') -> characteristic_two_field; +supportedCurvesTypes(?'prime-field') -> prime_field. + +namedCurves(?'sect571r1') -> sect571r1; +namedCurves(?'sect571k1') -> sect571k1; +namedCurves(?'sect409r1') -> sect409r1; +namedCurves(?'sect409k1') -> sect409k1; +namedCurves(?'secp521r1') -> secp521r1; +namedCurves(?'secp384r1') -> secp384r1; +namedCurves(?'secp224r1') -> secp224r1; +namedCurves(?'secp224k1') -> secp224k1; +namedCurves(?'secp192k1') -> secp192k1; +namedCurves(?'secp160r2') -> secp160r2; +namedCurves(?'secp128r2') -> secp128r2; +namedCurves(?'secp128r1') -> secp128r1; +namedCurves(?'sect233r1') -> sect233r1; +namedCurves(?'sect233k1') -> sect233k1; +namedCurves(?'sect193r2') -> sect193r2; +namedCurves(?'sect193r1') -> sect193r1; +namedCurves(?'sect131r2') -> sect131r2; +namedCurves(?'sect131r1') -> sect131r1; +namedCurves(?'sect283r1') -> sect283r1; +namedCurves(?'sect283k1') -> sect283k1; +namedCurves(?'sect163r2') -> sect163r2; +namedCurves(?'secp256k1') -> secp256k1; +namedCurves(?'secp160k1') -> secp160k1; +namedCurves(?'secp160r1') -> secp160r1; +namedCurves(?'secp112r2') -> secp112r2; +namedCurves(?'secp112r1') -> secp112r1; +namedCurves(?'sect113r2') -> sect113r2; +namedCurves(?'sect113r1') -> sect113r1; +namedCurves(?'sect239k1') -> sect239k1; +namedCurves(?'sect163r1') -> sect163r1; +namedCurves(?'sect163k1') -> sect163k1; +namedCurves(?'secp256r1') -> secp256r1; +namedCurves(?'secp192r1') -> secp192r1; + +namedCurves(sect571r1) -> ?'sect571r1'; +namedCurves(sect571k1) -> ?'sect571k1'; +namedCurves(sect409r1) -> ?'sect409r1'; +namedCurves(sect409k1) -> ?'sect409k1'; +namedCurves(secp521r1) -> ?'secp521r1'; +namedCurves(secp384r1) -> ?'secp384r1'; +namedCurves(secp224r1) -> ?'secp224r1'; +namedCurves(secp224k1) -> ?'secp224k1'; +namedCurves(secp192k1) -> ?'secp192k1'; +namedCurves(secp160r2) -> ?'secp160r2'; +namedCurves(secp128r2) -> ?'secp128r2'; +namedCurves(secp128r1) -> ?'secp128r1'; +namedCurves(sect233r1) -> ?'sect233r1'; +namedCurves(sect233k1) -> ?'sect233k1'; +namedCurves(sect193r2) -> ?'sect193r2'; +namedCurves(sect193r1) -> ?'sect193r1'; +namedCurves(sect131r2) -> ?'sect131r2'; +namedCurves(sect131r1) -> ?'sect131r1'; +namedCurves(sect283r1) -> ?'sect283r1'; +namedCurves(sect283k1) -> ?'sect283k1'; +namedCurves(sect163r2) -> ?'sect163r2'; +namedCurves(secp256k1) -> ?'secp256k1'; +namedCurves(secp160k1) -> ?'secp160k1'; +namedCurves(secp160r1) -> ?'secp160r1'; +namedCurves(secp112r2) -> ?'secp112r2'; +namedCurves(secp112r1) -> ?'secp112r1'; +namedCurves(sect113r2) -> ?'sect113r2'; +namedCurves(sect113r1) -> ?'sect113r1'; +namedCurves(sect239k1) -> ?'sect239k1'; +namedCurves(sect163r1) -> ?'sect163r1'; +namedCurves(sect163k1) -> ?'sect163k1'; +namedCurves(secp256r1) -> ?'secp256r1'; +namedCurves(secp192r1) -> ?'secp192r1'. + %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- @@ -111,14 +183,24 @@ decode_supportedPublicKey(#'OTPSubjectPublicKeyInfo'{algorithm= PA = #'PublicKeyAlgorithm'{algorithm=Algo}, subjectPublicKey = {0,SPK0}}) -> Type = supportedPublicKeyAlgorithms(Algo), - {ok, SPK} = 'OTP-PUB-KEY':decode(Type, SPK0), + SPK = case Type of + 'ECPoint' -> #'ECPoint'{point = SPK0}; + _ -> {ok, SPK1} = 'OTP-PUB-KEY':decode(Type, SPK0), + SPK1 + end, #'OTPSubjectPublicKeyInfo'{subjectPublicKey = SPK, algorithm=PA}. encode_supportedPublicKey(#'OTPSubjectPublicKeyInfo'{algorithm= PA = #'PublicKeyAlgorithm'{algorithm=Algo}, subjectPublicKey = SPK0}) -> Type = supportedPublicKeyAlgorithms(Algo), - {ok, SPK} = 'OTP-PUB-KEY':encode(Type, SPK0), + SPK = case Type of + 'ECPoint' -> + SPK0#'ECPoint'.point; + _ -> + {ok, SPK1} = 'OTP-PUB-KEY':encode(Type, SPK0), + SPK1 + end, #'OTPSubjectPublicKeyInfo'{subjectPublicKey = {0,SPK}, algorithm=PA}. %%% Extensions diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl index 6bdc35fb79..746d142ec3 100644 --- a/lib/public_key/src/pubkey_pem.erl +++ b/lib/public_key/src/pubkey_pem.erl @@ -202,7 +202,11 @@ pem_start('CertificationRequest') -> pem_start('ContentInfo') -> <<"-----BEGIN PKCS7-----">>; pem_start('CertificateList') -> - <<"-----BEGIN X509 CRL-----">>. + <<"-----BEGIN X509 CRL-----">>; +pem_start('OTPEcpkParameters') -> + <<"-----BEGIN EC PARAMETERS-----">>; +pem_start('ECPrivateKey') -> + <<"-----BEGIN EC PRIVATE KEY-----">>. pem_end(<<"-----BEGIN CERTIFICATE-----">>) -> <<"-----END CERTIFICATE-----">>; @@ -226,6 +230,10 @@ pem_end(<<"-----BEGIN PKCS7-----">>) -> <<"-----END PKCS7-----">>; pem_end(<<"-----BEGIN X509 CRL-----">>) -> <<"-----END X509 CRL-----">>; +pem_end(<<"-----BEGIN EC PARAMETERS-----">>) -> + <<"-----END EC PARAMETERS-----">>; +pem_end(<<"-----BEGIN EC PRIVATE KEY-----">>) -> + <<"-----END EC PRIVATE KEY-----">>; pem_end(_) -> undefined. @@ -250,7 +258,11 @@ asn1_type(<<"-----BEGIN CERTIFICATE REQUEST-----">>) -> asn1_type(<<"-----BEGIN PKCS7-----">>) -> 'ContentInfo'; asn1_type(<<"-----BEGIN X509 CRL-----">>) -> - 'CertificateList'. + 'CertificateList'; +asn1_type(<<"-----BEGIN EC PARAMETERS-----">>) -> + 'OTPEcpkParameters'; +asn1_type(<<"-----BEGIN EC PRIVATE KEY-----">>) -> + 'ECPrivateKey'. pem_decrypt() -> <<"Proc-Type: 4,ENCRYPTED">>. diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 736c18cdd4..6c25428ea4 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -94,7 +94,9 @@ pem_entry_decode({'SubjectPublicKeyInfo', Der, _}) -> der_decode(KeyType, Key0); 'DSAPublicKey' -> {params, DssParams} = der_decode('DSAParams', Params), - {der_decode(KeyType, Key0), DssParams} + {der_decode(KeyType, Key0), DssParams}; + 'ECPrivateKey' -> + der_decode(KeyType, Key0) end; pem_entry_decode({Asn1Type, Der, not_encrypted}) when is_atom(Asn1Type), is_binary(Der) -> @@ -336,6 +338,40 @@ format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, privateExponent = D}) -> [crypto:mpint(K) || K <- [E, N, D]]. +%% +%% Description: convert a ECPrivate key into resource Key +%%-------------------------------------------------------------------- +list2int(L) -> + S = length(L) * 8, + <> = erlang:iolist_to_binary(L), + R. + +ec_private_key_to_eckey(#'ECPrivateKey'{privateKey = PrivKey, + parameters = Param, + publicKey = _PubKey}) -> + ECCurve = case Param of + #'OTPECParameters'{ fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor } -> + Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), FieldId#'OTPFieldID'.parameters}, + Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, + {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; + {namedCurve, OID} -> + pubkey_cert_records:namedCurves(OID) + end, + Key = {ECCurve, list2int(PrivKey), undefined}, + {'ECKey', crypto:term_to_ec_key(Key)}. + +ec_public_key_to_eckey({#'ECPoint'{point = ECPoint}, Param}) -> + ECCurve = case Param of + #'OTPECParameters'{ fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor } -> + Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), FieldId#'OTPFieldID'.parameters}, + Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, + {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; + {namedCurve, OID} -> + pubkey_cert_records:namedCurves(OID) + end, + Key = {ECCurve, undefined, ECPoint}, + {'ECKey', crypto:term_to_ec_key(Key)}. + %%-------------------------------------------------------------------- -spec pkix_sign_types(SignatureAlg::oid()) -> @@ -362,7 +398,15 @@ pkix_sign_types(?md5WithRSAEncryption) -> pkix_sign_types(?'id-dsa-with-sha1') -> {sha, dsa}; pkix_sign_types(?'id-dsaWithSHA1') -> - {sha, dsa}. + {sha, dsa}; +pkix_sign_types(?'ecdsa-with-SHA1') -> + {sha, ecdsa}; +pkix_sign_types(?'ecdsa-with-SHA256') -> + {sha256, ecdsa}; +pkix_sign_types(?'ecdsa-with-SHA384') -> + {sha384, ecdsa}; +pkix_sign_types(?'ecdsa-with-SHA512') -> + {sha512, ecdsa}. %%-------------------------------------------------------------------- -spec sign(binary() | {digest, binary()}, rsa_digest_type() | dss_digest_type(), @@ -386,6 +430,18 @@ sign(PlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> [crypto:mpint(P), crypto:mpint(Q), crypto:mpint(G), crypto:mpint(X)]); +sign(Digest, DigestType, Key = {?'id-ecPublicKey', _, _}) -> + sign(Digest, DigestType, ec_public_key_to_eckey(Key)); + +sign(Digest, DigestType, Key = #'ECPrivateKey'{}) -> + sign(Digest, DigestType, ec_private_key_to_eckey(Key)); + +sign({digest,_}=Digest, DigestType, {'ECKey', Key}) -> + crypto:ecdsa_sign(DigestType, Digest, Key); + +sign(PlainText, DigestType, {'ECKey', Key}) -> + crypto:ecdsa_sign(DigestType, sized_binary(PlainText), Key); + %% Backwards compatible sign(Digest, none, #'DSAPrivateKey'{} = Key) -> sign({digest,Digest}, sha, Key). @@ -414,6 +470,24 @@ verify({digest,_}=Digest, sha, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = crypto:dss_verify(Digest, sized_binary(Signature), [crypto:mpint(P), crypto:mpint(Q), crypto:mpint(G), crypto:mpint(Key)]); + +verify({digest,_}=Digest, DigestType, Signature, {'ECKey', Key}) -> + crypto:ecdsa_verify(DigestType, Digest, + sized_binary(Signature), + Key); + +verify(PlainText, DigestType, Signature, Key = #'ECPrivateKey'{}) -> + verify(PlainText, DigestType, Signature, ec_private_key_to_eckey(Key)); + +verify(PlainText, DigestType, Signature, Key = {#'ECPoint'{}, _}) -> + verify(PlainText, DigestType, Signature, ec_public_key_to_eckey(Key)); + +verify(PlainText, DigestType, Signature, {'ECKey', Key}) -> + crypto:ecdsa_verify(DigestType, + sized_binary(PlainText), + sized_binary(Signature), + Key); + %% Backwards compatibility verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) -> verify({digest,Digest}, sha, Signature, Key); @@ -458,7 +532,17 @@ pkix_verify(DerCert, {Key, #'Dss-Parms'{}} = DSAKey) pkix_verify(DerCert, #'RSAPublicKey'{} = RSAKey) when is_binary(DerCert) -> {DigestType, PlainText, Signature} = pubkey_cert:verify_data(DerCert), - verify(PlainText, DigestType, Signature, RSAKey). + verify(PlainText, DigestType, Signature, RSAKey); + +pkix_verify(DerCert, #'ECPrivateKey'{} = ECKey) + when is_binary(DerCert) -> + {DigestType, PlainText, Signature} = pubkey_cert:verify_data(DerCert), + verify(PlainText, DigestType, Signature, ECKey); + +pkix_verify(DerCert, Key = {'ECKey', _}) + when is_binary(DerCert) -> + {DigestType, PlainText, Signature} = pubkey_cert:verify_data(DerCert), + verify(PlainText, DigestType, Signature, Key). %%-------------------------------------------------------------------- -spec pkix_is_issuer(Cert :: der_encoded()| #'OTPCertificate'{} | #'CertificateList'{}, diff --git a/lib/public_key/test/erl_make_certs.erl b/lib/public_key/test/erl_make_certs.erl index 897cf2f350..14efbcc7e0 100644 --- a/lib/public_key/test/erl_make_certs.erl +++ b/lib/public_key/test/erl_make_certs.erl @@ -45,7 +45,7 @@ %% {dnQualifer, DnQ} %% issuer = {Issuer, IssuerKey} true (i.e. a ca cert is created) %% (obs IssuerKey migth be {Key, Password} -%% key = KeyFile|KeyBin|rsa|dsa Subject PublicKey rsa or dsa generates key +%% key = KeyFile|KeyBin|rsa|dsa|ec Subject PublicKey rsa, dsa or ec generates key %% %% %% (OBS: The generated keys are for testing only) @@ -90,6 +90,16 @@ gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) -> Key = gen_dsa2(LSize, NSize), {Key, encode_key(Key)}. +%%-------------------------------------------------------------------- +%% @doc Creates a ec key (OBS: for testing only) +%% the sizes are in bytes +%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()} +%% @end +%%-------------------------------------------------------------------- +gen_ec(Curve) when is_atom(Curve) -> + Key = gen_ec2(Curve), + {Key, encode_key(Key)}. + %%-------------------------------------------------------------------- %% @doc Verifies cert signatures %% @spec (::binary(), ::tuple()) -> ::boolean() @@ -102,7 +112,10 @@ verify_signature(DerEncodedCert, DerKey, _KeyParams) -> public_key:pkix_verify(DerEncodedCert, #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}); #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y} -> - public_key:pkix_verify(DerEncodedCert, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}) + public_key:pkix_verify(DerEncodedCert, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}); + #'ECPrivateKey'{version = _Version, privateKey = _PrivKey, + parameters = _Params, publicKey = _PubKey} -> + public_key:pkix_verify(DerEncodedCert, Key) end. %%%%%%%%%%%%%%%%%%%%%%%%% Implementation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -112,6 +125,7 @@ get_key(Opts) -> undefined -> make_key(rsa, Opts); rsa -> make_key(rsa, Opts); dsa -> make_key(dsa, Opts); + ec -> make_key(ec, Opts); Key -> Password = proplists:get_value(password, Opts, no_passwd), decode_key(Key, Password) @@ -129,6 +143,8 @@ decode_key(#'RSAPrivateKey'{} = Key,_) -> Key; decode_key(#'DSAPrivateKey'{} = Key,_) -> Key; +decode_key(#'ECPrivateKey'{} = Key,_) -> + Key; decode_key(PemEntry = {_,_,_}, Pw) -> public_key:pem_entry_decode(PemEntry, Pw); decode_key(PemBin, Pw) -> @@ -140,7 +156,10 @@ encode_key(Key = #'RSAPrivateKey'{}) -> {'RSAPrivateKey', Der, not_encrypted}; encode_key(Key = #'DSAPrivateKey'{}) -> {ok, Der} = 'OTP-PUB-KEY':encode('DSAPrivateKey', Key), - {'DSAPrivateKey', Der, not_encrypted}. + {'DSAPrivateKey', Der, not_encrypted}; +encode_key(Key = #'ECPrivateKey'{}) -> + {ok, Der} = 'OTP-PUB-KEY':encode('ECPrivateKey', Key), + {'ECPrivateKey', Der, not_encrypted}. make_tbs(SubjectKey, Opts) -> Version = list_to_atom("v"++integer_to_list(proplists:get_value(version, Opts, 3))), @@ -282,7 +301,14 @@ publickey(#'RSAPrivateKey'{modulus=N, publicExponent=E}) -> publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) -> Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa', parameters={params, #'Dss-Parms'{p=P, q=Q, g=G}}}, - #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y}. + #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y}; +publickey(#'ECPrivateKey'{version = _Version, + privateKey = _PrivKey, + parameters = Params, + publicKey = {0, PubKey}}) -> + Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-ecPublicKey', parameters=Params}, + #'OTPSubjectPublicKeyInfo'{algorithm = Algo, + subjectPublicKey = #'ECPoint'{point = PubKey}}. validity(Opts) -> DefFrom0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())-1), @@ -303,13 +329,24 @@ sign_algorithm(#'RSAPrivateKey'{}, Opts) -> end, {Type, 'NULL'}; sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) -> - {?'id-dsa-with-sha1', {params,#'Dss-Parms'{p=P, q=Q, g=G}}}. + {?'id-dsa-with-sha1', {params,#'Dss-Parms'{p=P, q=Q, g=G}}}; +sign_algorithm(#'ECPrivateKey'{}, Opts) -> + Type = case proplists:get_value(digest, Opts, sha1) of + sha1 -> ?'ecdsa-with-SHA1'; + sha512 -> ?'ecdsa-with-SHA512'; + sha384 -> ?'ecdsa-with-SHA384'; + sha256 -> ?'ecdsa-with-SHA256' + end, + {Type, 'NULL'}. make_key(rsa, _Opts) -> %% (OBS: for testing only) gen_rsa2(64); make_key(dsa, _Opts) -> - gen_dsa2(128, 20). %% Bytes i.e. {1024, 160} + gen_dsa2(128, 20); %% Bytes i.e. {1024, 160} +make_key(ec, _Opts) -> + %% (OBS: for testing only) + gen_ec2(secp256k1). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% RSA key generation (OBS: for testing only) @@ -368,6 +405,24 @@ gen_dsa2(LSize, NSize) -> #'DSAPrivateKey'{version=0, p=P, q=Q, g=G, y=Y, x=X} end. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EC key generation (OBS: for testing only) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +int2list(I) -> + L = (length(integer_to_list(I, 16)) + 1) div 2, + binary_to_list(<>). + +gen_ec2(CurveId) -> + Key = crypto:ec_key_new(CurveId), + crypto:ec_key_generate(Key), + {_Curve, PrivKey, PubKey} = crypto:ec_key_to_term(Key), + + #'ECPrivateKey'{version = 1, + privateKey = int2list(PrivKey), + parameters = {namedCurve, pubkey_cert_records:namedCurves(CurveId)}, + publicKey = {0, PubKey}}. + %% See fips_186-3.pdf dsa_search(T, P0, Q, Iter) when Iter > 0 -> P = 2*T*Q*P0 + 1, -- cgit v1.2.3 From ff58cc8976efe77f92510011d9ed7b0f242e235e Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Mon, 8 Apr 2013 16:07:56 +0200 Subject: public_key: Use new crypto API functions sign and verify --- lib/public_key/src/public_key.erl | 72 ++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 38 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 6c25428ea4..91d33fab42 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -256,7 +256,7 @@ decrypt_private(CipherText, is_integer(N), is_integer(E), is_integer(D), is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_decrypt(CipherText, format_rsa_private_key(Key), Padding). + crypto:rsa_private_decrypt(CipherText, old_format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- -spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key()) -> @@ -322,7 +322,7 @@ encrypt_private(PlainText, is_integer(N), is_integer(E), is_integer(D), is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_encrypt(PlainText, format_rsa_private_key(Key), Padding). + crypto:rsa_private_encrypt(PlainText, old_format_rsa_private_key(Key), Padding). format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, @@ -332,10 +332,23 @@ format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, coefficient = C}) when is_integer(P1), is_integer(P2), is_integer(E1), is_integer(E2), is_integer(C) -> - [crypto:mpint(K) || K <- [E, N, D, P1, P2, E1, E2, C]]; + [K || K <- [E, N, D, P1, P2, E1, E2, C]]; format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, privateExponent = D}) -> + [K || K <- [E, N, D]]. + +old_format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D, + prime1 = P1, prime2 = P2, + exponent1 = E1, exponent2 = E2, + coefficient = C}) + when is_integer(P1), is_integer(P2), + is_integer(E1), is_integer(E2), is_integer(C) -> + [crypto:mpint(K) || K <- [E, N, D, P1, P2, E1, E2, C]]; + +old_format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D}) -> [crypto:mpint(K) || K <- [E, N, D]]. %% @@ -415,20 +428,16 @@ pkix_sign_types(?'ecdsa-with-SHA512') -> %% Description: Create digital signature. %%-------------------------------------------------------------------- sign({digest,_}=Digest, DigestType, Key = #'RSAPrivateKey'{}) -> - crypto:rsa_sign(DigestType, Digest, format_rsa_private_key(Key)); + crypto:sign(rsa, DigestType, Digest, format_rsa_private_key(Key)); sign(PlainText, DigestType, Key = #'RSAPrivateKey'{}) -> - crypto:rsa_sign(DigestType, sized_binary(PlainText), format_rsa_private_key(Key)); + crypto:sign(rsa, DigestType, PlainText, format_rsa_private_key(Key)); sign({digest,_}=Digest, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> - crypto:dss_sign(Digest, - [crypto:mpint(P), crypto:mpint(Q), - crypto:mpint(G), crypto:mpint(X)]); + crypto:sign(dss, sha, Digest, [P, Q, G, X]); sign(PlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> - crypto:dss_sign(sized_binary(PlainText), - [crypto:mpint(P), crypto:mpint(Q), - crypto:mpint(G), crypto:mpint(X)]); + crypto:sign(dss, sha, PlainText, [P, Q, G, X]); sign(Digest, DigestType, Key = {?'id-ecPublicKey', _, _}) -> sign(Digest, DigestType, ec_public_key_to_eckey(Key)); @@ -437,10 +446,10 @@ sign(Digest, DigestType, Key = #'ECPrivateKey'{}) -> sign(Digest, DigestType, ec_private_key_to_eckey(Key)); sign({digest,_}=Digest, DigestType, {'ECKey', Key}) -> - crypto:ecdsa_sign(DigestType, Digest, Key); + crypto:sign(ecdsa, DigestType, Digest, Key); sign(PlainText, DigestType, {'ECKey', Key}) -> - crypto:ecdsa_sign(DigestType, sized_binary(PlainText), Key); + crypto:sign(ecdsa, DigestType, PlainText, Key); %% Backwards compatible sign(Digest, none, #'DSAPrivateKey'{} = Key) -> @@ -452,29 +461,21 @@ sign(Digest, none, #'DSAPrivateKey'{} = Key) -> | dsa_public_key()) -> boolean(). %% Description: Verifies a digital signature. %%-------------------------------------------------------------------- -verify({digest,_}=Digest, DigestType, Signature, +verify({digest,_} = Digest, DigestType, Signature, #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) -> - crypto:rsa_verify(DigestType, Digest, - sized_binary(Signature), - [crypto:mpint(Exp), crypto:mpint(Mod)]); + crypto:verify(rsa, DigestType, Digest, Signature, [Exp, Mod]); verify(PlainText, DigestType, Signature, #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) -> - crypto:rsa_verify(DigestType, - sized_binary(PlainText), - sized_binary(Signature), - [crypto:mpint(Exp), crypto:mpint(Mod)]); + crypto:verify(rsa, DigestType, PlainText, Signature, + [Exp, Mod]); -verify({digest,_}=Digest, sha, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) +verify({digest,_} = Digest, sha = DigestType, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) when is_integer(Key), is_binary(Signature) -> - crypto:dss_verify(Digest, sized_binary(Signature), - [crypto:mpint(P), crypto:mpint(Q), - crypto:mpint(G), crypto:mpint(Key)]); + crypto:verify(dss, DigestType, Digest, Signature, [P, Q, G, Key]); -verify({digest,_}=Digest, DigestType, Signature, {'ECKey', Key}) -> - crypto:ecdsa_verify(DigestType, Digest, - sized_binary(Signature), - Key); +verify({digest,_} = Digest, DigestType, Signature, {'ECKey', Key}) -> + crypto:verify(ecdsa, DigestType, Digest, Signature, Key); verify(PlainText, DigestType, Signature, Key = #'ECPrivateKey'{}) -> verify(PlainText, DigestType, Signature, ec_private_key_to_eckey(Key)); @@ -483,21 +484,16 @@ verify(PlainText, DigestType, Signature, Key = {#'ECPoint'{}, _}) -> verify(PlainText, DigestType, Signature, ec_public_key_to_eckey(Key)); verify(PlainText, DigestType, Signature, {'ECKey', Key}) -> - crypto:ecdsa_verify(DigestType, - sized_binary(PlainText), - sized_binary(Signature), - Key); + crypto:verify(ecdsa, DigestType, PlainText, Signature, Key); %% Backwards compatibility verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) -> verify({digest,Digest}, sha, Signature, Key); -verify(PlainText, sha, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) +verify(PlainText, sha = DigestType, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) when is_integer(Key), is_binary(PlainText), is_binary(Signature) -> - crypto:dss_verify(sized_binary(PlainText), - sized_binary(Signature), - [crypto:mpint(P), crypto:mpint(Q), - crypto:mpint(G), crypto:mpint(Key)]). + crypto:verify(dss, DigestType, PlainText, Signature, [P, Q, G, Key]). + %%-------------------------------------------------------------------- -spec pkix_sign(#'OTPTBSCertificate'{}, rsa_private_key() | dsa_private_key()) -> Der::binary(). -- cgit v1.2.3 From 7030e089d1090e3b9a95c96737b36d6d6fc6ef97 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Tue, 16 Apr 2013 11:48:25 +0200 Subject: public_key: Eliminate mpints in rsa_public/private_encrypt/decrypt --- lib/public_key/src/public_key.erl | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 91d33fab42..4b8fda8d40 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -253,10 +253,9 @@ decrypt_private(CipherText, privateExponent = D} = Key, Options) when is_binary(CipherText), - is_integer(N), is_integer(E), is_integer(D), is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_decrypt(CipherText, old_format_rsa_private_key(Key), Padding). + crypto:rsa_private_decrypt(CipherText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- -spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key()) -> @@ -320,36 +319,25 @@ encrypt_private(PlainText, Options) when is_binary(PlainText), is_integer(N), is_integer(E), is_integer(D), - is_list(Options) -> + is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_encrypt(PlainText, old_format_rsa_private_key(Key), Padding). - + crypto:rsa_private_encrypt(PlainText, format_rsa_private_key(Key), Padding). format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, privateExponent = D, prime1 = P1, prime2 = P2, exponent1 = E1, exponent2 = E2, coefficient = C}) - when is_integer(P1), is_integer(P2), + when is_integer(N), is_integer(E), is_integer(D), + is_integer(P1), is_integer(P2), is_integer(E1), is_integer(E2), is_integer(C) -> - [K || K <- [E, N, D, P1, P2, E1, E2, C]]; + [E, N, D, P1, P2, E1, E2, C]; format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, - privateExponent = D}) -> - [K || K <- [E, N, D]]. - -old_format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, - privateExponent = D, - prime1 = P1, prime2 = P2, - exponent1 = E1, exponent2 = E2, - coefficient = C}) - when is_integer(P1), is_integer(P2), - is_integer(E1), is_integer(E2), is_integer(C) -> - [crypto:mpint(K) || K <- [E, N, D, P1, P2, E1, E2, C]]; - -old_format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, - privateExponent = D}) -> - [crypto:mpint(K) || K <- [E, N, D]]. + privateExponent = D}) when is_integer(N), + is_integer(E), + is_integer(D) -> + [E, N, D]. %% %% Description: convert a ECPrivate key into resource Key @@ -720,12 +708,12 @@ do_pem_entry_decode({Asn1Type,_, _} = PemEntry, Password) -> encrypt_public(PlainText, N, E, Options)-> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_public_encrypt(PlainText, [crypto:mpint(E),crypto:mpint(N)], + crypto:rsa_public_encrypt(PlainText, [E,N], Padding). decrypt_public(CipherText, N,E, Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_public_decrypt(CipherText,[crypto:mpint(E), crypto:mpint(N)], + crypto:rsa_public_decrypt(CipherText,[E, N], Padding). path_validation([], #path_validation_state{working_public_key_algorithm -- cgit v1.2.3 From dfd9c13f882ef199dfcb830823cb12d83bcc4f10 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Wed, 17 Apr 2013 10:28:25 +0200 Subject: ssl & public_key: New public_key API for DH/ECDH/SRP keys --- lib/public_key/src/public_key.erl | 192 +++++++++++++++++++++++++------------- 1 file changed, 129 insertions(+), 63 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 4b8fda8d40..41ebaef76d 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -34,7 +34,8 @@ decrypt_private/2, decrypt_private/3, encrypt_public/2, encrypt_public/3, decrypt_public/2, decrypt_public/3, - sign/3, verify/4, + sign/3, verify/4, generate_key/1, generate_key/2, + compute_key/2, compute_key/3, pkix_sign/2, pkix_verify/2, pkix_sign_types/1, pkix_is_self_signed/1, @@ -323,58 +324,70 @@ encrypt_private(PlainText, Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), crypto:rsa_private_encrypt(PlainText, format_rsa_private_key(Key), Padding). -format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, - privateExponent = D, - prime1 = P1, prime2 = P2, - exponent1 = E1, exponent2 = E2, - coefficient = C}) - when is_integer(N), is_integer(E), is_integer(D), - is_integer(P1), is_integer(P2), - is_integer(E1), is_integer(E2), is_integer(C) -> - [E, N, D, P1, P2, E1, E2, C]; - -format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, - privateExponent = D}) when is_integer(N), - is_integer(E), - is_integer(D) -> - [E, N, D]. +%%-------------------------------------------------------------------- +-spec generate_key(#'ECPrivateKey'{} | {curve, Name ::atom()} | #'DHParameter'{}) -> {'ECKey', term()} | {binary(), binary()}. +-spec generate_key(#'ECPoint'{}, #'OTPECParameters'{} | {namedCurve, oid()}) -> {'ECKey', term()}. -%% -%% Description: convert a ECPrivate key into resource Key +%% Description: Generates new key(s) %%-------------------------------------------------------------------- -list2int(L) -> - S = length(L) * 8, - <> = erlang:iolist_to_binary(L), - R. +generate_key(#'ECPrivateKey'{} = Key) -> + ec_private_key_to_eckey(Key); -ec_private_key_to_eckey(#'ECPrivateKey'{privateKey = PrivKey, - parameters = Param, - publicKey = _PubKey}) -> - ECCurve = case Param of - #'OTPECParameters'{ fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor } -> - Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), FieldId#'OTPFieldID'.parameters}, - Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, - {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; - {namedCurve, OID} -> - pubkey_cert_records:namedCurves(OID) - end, - Key = {ECCurve, list2int(PrivKey), undefined}, - {'ECKey', crypto:term_to_ec_key(Key)}. +generate_key({curve, Name}) -> + %% TODO: Better crypto API + ECDHKey = crypto:ec_key_new(Name), + crypto:ec_key_generate(ECDHKey), + crypto:ec_key_to_term(ECDHKey); -ec_public_key_to_eckey({#'ECPoint'{point = ECPoint}, Param}) -> - ECCurve = case Param of - #'OTPECParameters'{ fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor } -> - Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), FieldId#'OTPFieldID'.parameters}, - Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, - {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; - {namedCurve, OID} -> - pubkey_cert_records:namedCurves(OID) - end, - Key = {ECCurve, undefined, ECPoint}, - {'ECKey', crypto:term_to_ec_key(Key)}. +generate_key(#'DHParameter'{prime = P, base = G}) -> + crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]); + +generate_key({dh, Prime, Base}) when is_binary(Prime), is_binary(Base) -> + %% TODO: Is mpint could be normal binary! + crypto:dh_generate_key([Prime, Base]); + +generate_key({srp, Version, Generator, Prime}) when is_binary(Generator), is_binary(Prime) -> + crypto:srp_generate_key(Generator, Prime, Version); + +generate_key({srp, Version, Verifier, Generator, Prime}) when is_binary(Verifier), is_binary(Generator), is_binary(Prime) -> + crypto:srp_generate_key(Verifier, Generator, Prime, Version). + +generate_key(#'ECPoint'{} = Key, Params) -> + %% TODO: Better crypto API + ECKey = ec_public_key_to_eckey({Key,Params}), + ECClntKey = crypto:term_to_ec_key(ECKey), + crypto:ec_key_generate(ECClntKey), + crypto:ec_key_to_term(ECClntKey). %%-------------------------------------------------------------------- +-spec compute_key(#'ECPoint'{}, {'ECKey', binary()}) -> binary(). +-spec compute_key(OthersKey ::binary(), MyKey::binary() | {binary(), binary()}, + {dh, binary(), binary()} | + {srp, atom(), binary(), binary()} | + {srp, string(), string(), binary(), atom(), binary(), binary()}) + -> binary(). +%% Description: Compute shared secret +%%-------------------------------------------------------------------- +compute_key(#'ECPoint'{point = Point}, Term) -> + %% TODO: Better crypto API + ECKey = crypto:term_to_ec_key(Term), + crypto:ecdh_compute_key(ECKey, Point). + +compute_key(OthersKey, MyKey, {dh, Prime, Base}) when is_binary(OthersKey), + is_binary(MyKey), + is_binary(Prime), + is_binary(Base) -> + %% TODO: Is mpint could be binary! + crypto:dh_compute_key(OthersKey, MyKey, [Prime, Base]); + +compute_key(ClientPub, {ServerPub, ServerPriv}, {srp, Version, Verifier, Prime}) -> + crypto:srp_compute_key(Verifier, Prime, ClientPub, ServerPub, ServerPriv, Version); + +compute_key(ServerPub, {ClientPub, ClientPriv}, {srp, Username, Password, Salt, Version, Prime, Generator}) -> + DerivedKey = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]), + crypto:srp_compute_key(DerivedKey, Prime, Generator, ClientPub, ClientPriv, ServerPub, Version). +%%-------------------------------------------------------------------- -spec pkix_sign_types(SignatureAlg::oid()) -> %% Relevant dsa digest type is subpart of rsa digest type { DigestType :: rsa_digest_type(), @@ -430,14 +443,15 @@ sign(PlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> sign(Digest, DigestType, Key = {?'id-ecPublicKey', _, _}) -> sign(Digest, DigestType, ec_public_key_to_eckey(Key)); -sign(Digest, DigestType, Key = #'ECPrivateKey'{}) -> - sign(Digest, DigestType, ec_private_key_to_eckey(Key)); - -sign({digest,_}=Digest, DigestType, {'ECKey', Key}) -> - crypto:sign(ecdsa, DigestType, Digest, Key); +sign({digest,_} = Digest, DigestType, Key = #'ECPrivateKey'{}) -> + ECDHKey = ec_private_key_to_eckey(Key), + ECKey = crypto:term_to_ec_key(ECDHKey), + crypto:sign(ecdsa, DigestType, Digest, ECKey); -sign(PlainText, DigestType, {'ECKey', Key}) -> - crypto:sign(ecdsa, DigestType, PlainText, Key); +sign(PlainText, DigestType, Key = #'ECPrivateKey'{}) -> + ECDHKey = ec_private_key_to_eckey(Key), + ECKey = crypto:term_to_ec_key(ECDHKey), + crypto:sign(ecdsa, DigestType, PlainText, ECKey); %% Backwards compatible sign(Digest, none, #'DSAPrivateKey'{} = Key) -> @@ -462,17 +476,15 @@ verify({digest,_} = Digest, sha = DigestType, Signature, {Key, #'Dss-Parms'{p = when is_integer(Key), is_binary(Signature) -> crypto:verify(dss, DigestType, Digest, Signature, [P, Q, G, Key]); -verify({digest,_} = Digest, DigestType, Signature, {'ECKey', Key}) -> - crypto:verify(ecdsa, DigestType, Digest, Signature, Key); - -verify(PlainText, DigestType, Signature, Key = #'ECPrivateKey'{}) -> - verify(PlainText, DigestType, Signature, ec_private_key_to_eckey(Key)); +verify(Digest, DigestType, Signature, Key = #'ECPrivateKey'{}) -> + ECDHKey = ec_private_key_to_eckey(Key), + ECKey = crypto:term_to_ec_key(ECDHKey), + crypto:verify(ecdsa, DigestType, Digest, Signature, ECKey); -verify(PlainText, DigestType, Signature, Key = {#'ECPoint'{}, _}) -> - verify(PlainText, DigestType, Signature, ec_public_key_to_eckey(Key)); - -verify(PlainText, DigestType, Signature, {'ECKey', Key}) -> - crypto:verify(ecdsa, DigestType, PlainText, Signature, Key); +verify(Digest, DigestType, Signature, Key = {#'ECPoint'{}, _}) -> + ECDHKey = ec_public_key_to_eckey(Key), + ECKey = crypto:term_to_ec_key(ECDHKey), + crypto:verify(ecdsa, DigestType, Digest, Signature, ECKey); %% Backwards compatibility verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) -> @@ -910,3 +922,57 @@ combine(CRL, DeltaCRLs) -> end, lists:foldl(Fun, hd(Deltas), tl(Deltas)) end. + +format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D, + prime1 = P1, prime2 = P2, + exponent1 = E1, exponent2 = E2, + coefficient = C}) + when is_integer(N), is_integer(E), is_integer(D), + is_integer(P1), is_integer(P2), + is_integer(E1), is_integer(E2), is_integer(C) -> + [E, N, D, P1, P2, E1, E2, C]; + +format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D}) when is_integer(N), + is_integer(E), + is_integer(D) -> + [E, N, D]. + +%% +%% Description: convert a ECPrivate key into resource Key +%%-------------------------------------------------------------------- +list2int(L) -> + S = length(L) * 8, + <> = erlang:iolist_to_binary(L), + R. + +ec_private_key_to_eckey(#'ECPrivateKey'{privateKey = PrivKey, + parameters = Param, + publicKey = _PubKey}) -> + ECCurve = + case Param of + #'OTPECParameters'{ fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor } -> + Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), + FieldId#'OTPFieldID'.parameters}, + Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, + {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; + {namedCurve, OID} -> + pubkey_cert_records:namedCurves(OID) + end, + {ECCurve, list2int(PrivKey), undefined}. + %%{'ECKey', crypto:term_to_ec_key(Key)}. + +ec_public_key_to_eckey({#'ECPoint'{point = ECPoint}, Param}) -> + ECCurve = + case Param of + #'OTPECParameters'{ fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor } -> + Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), + FieldId#'OTPFieldID'.parameters}, + Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, + {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; + {namedCurve, OID} -> + pubkey_cert_records:namedCurves(OID) + end, + {ECCurve, undefined, ECPoint}. + %%{'ECKey', crypto:term_to_ec_key(Key)}. -- cgit v1.2.3 From 826ff38deec221e306b2f4a9ee529fae1dbbedf7 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Fri, 19 Apr 2013 15:47:47 +0200 Subject: ssl & public_key: Improved handling ECDH keys --- lib/public_key/src/public_key.erl | 163 ++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 88 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 41ebaef76d..06bffeea76 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -34,7 +34,8 @@ decrypt_private/2, decrypt_private/3, encrypt_public/2, encrypt_public/3, decrypt_public/2, decrypt_public/3, - sign/3, verify/4, generate_key/1, generate_key/2, + sign/3, verify/4, + generate_key/1, compute_key/2, compute_key/3, pkix_sign/2, pkix_verify/2, pkix_sign_types/1, @@ -326,18 +327,14 @@ encrypt_private(PlainText, %%-------------------------------------------------------------------- -spec generate_key(#'ECPrivateKey'{} | {curve, Name ::atom()} | #'DHParameter'{}) -> {'ECKey', term()} | {binary(), binary()}. --spec generate_key(#'ECPoint'{}, #'OTPECParameters'{} | {namedCurve, oid()}) -> {'ECKey', term()}. - %% Description: Generates new key(s) %%-------------------------------------------------------------------- -generate_key(#'ECPrivateKey'{} = Key) -> - ec_private_key_to_eckey(Key); - generate_key({curve, Name}) -> %% TODO: Better crypto API ECDHKey = crypto:ec_key_new(Name), crypto:ec_key_generate(ECDHKey), - crypto:ec_key_to_term(ECDHKey); + Term = crypto:ec_key_to_term(ECDHKey), + ec_key(Term); generate_key(#'DHParameter'{prime = P, base = G}) -> crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]); @@ -350,27 +347,33 @@ generate_key({srp, Version, Generator, Prime}) when is_binary(Generator), is_bin crypto:srp_generate_key(Generator, Prime, Version); generate_key({srp, Version, Verifier, Generator, Prime}) when is_binary(Verifier), is_binary(Generator), is_binary(Prime) -> - crypto:srp_generate_key(Verifier, Generator, Prime, Version). + crypto:srp_generate_key(Verifier, Generator, Prime, Version); -generate_key(#'ECPoint'{} = Key, Params) -> +generate_key(Params) -> %% TODO: Better crypto API - ECKey = ec_public_key_to_eckey({Key,Params}), - ECClntKey = crypto:term_to_ec_key(ECKey), + Name = ec_curve_spec(Params), + ECClntKey = crypto:ec_key_new(Name), + %% ECDHKey = format_ecdh_key(Params), + %% ECClntKey = crypto:term_to_ec_key(ECDHKey), crypto:ec_key_generate(ECClntKey), - crypto:ec_key_to_term(ECClntKey). + Term = crypto:ec_key_to_term(ECClntKey), + ec_key(Term, Params). %%-------------------------------------------------------------------- --spec compute_key(#'ECPoint'{}, {'ECKey', binary()}) -> binary(). +-spec compute_key(#'ECPoint'{}, #'ECPrivateKey'{} | crypto:ecdh_key()) -> binary(). -spec compute_key(OthersKey ::binary(), MyKey::binary() | {binary(), binary()}, {dh, binary(), binary()} | - {srp, atom(), binary(), binary()} | - {srp, string(), string(), binary(), atom(), binary(), binary()}) + {srp,'3'|'6'| '6a' , binary(), binary()} | + {srp, string(), string(), binary(), '3'|'6'| '6a', binary(), binary()}) -> binary(). %% Description: Compute shared secret %%-------------------------------------------------------------------- -compute_key(#'ECPoint'{point = Point}, Term) -> +compute_key(PubKey, #'ECPrivateKey'{} = PrivateKey) -> + compute_key(PubKey, format_ecdh_key(PrivateKey)); + +compute_key(#'ECPoint'{point = Point}, ECDHKeys) -> %% TODO: Better crypto API - ECKey = crypto:term_to_ec_key(Term), + ECKey = crypto:term_to_ec_key(ECDHKeys), crypto:ecdh_compute_key(ECKey, Point). compute_key(OthersKey, MyKey, {dh, Prime, Base}) when is_binary(OthersKey), @@ -428,30 +431,16 @@ pkix_sign_types(?'ecdsa-with-SHA512') -> dsa_private_key()) -> Signature :: binary(). %% Description: Create digital signature. %%-------------------------------------------------------------------- -sign({digest,_}=Digest, DigestType, Key = #'RSAPrivateKey'{}) -> - crypto:sign(rsa, DigestType, Digest, format_rsa_private_key(Key)); - -sign(PlainText, DigestType, Key = #'RSAPrivateKey'{}) -> - crypto:sign(rsa, DigestType, PlainText, format_rsa_private_key(Key)); - -sign({digest,_}=Digest, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> - crypto:sign(dss, sha, Digest, [P, Q, G, X]); +sign(DigestOrPlainText, DigestType, Key = #'RSAPrivateKey'{}) -> + crypto:sign(rsa, DigestType, DigestOrPlainText, format_rsa_private_key(Key)); -sign(PlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> - crypto:sign(dss, sha, PlainText, [P, Q, G, X]); +sign(DigestOrPlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> + crypto:sign(dss, sha, DigestOrPlainText, [P, Q, G, X]); -sign(Digest, DigestType, Key = {?'id-ecPublicKey', _, _}) -> - sign(Digest, DigestType, ec_public_key_to_eckey(Key)); - -sign({digest,_} = Digest, DigestType, Key = #'ECPrivateKey'{}) -> - ECDHKey = ec_private_key_to_eckey(Key), - ECKey = crypto:term_to_ec_key(ECDHKey), - crypto:sign(ecdsa, DigestType, Digest, ECKey); - -sign(PlainText, DigestType, Key = #'ECPrivateKey'{}) -> - ECDHKey = ec_private_key_to_eckey(Key), +sign(DigestOrPlainText, DigestType, Key = #'ECPrivateKey'{}) -> + ECDHKey = format_ecdh_key(Key), ECKey = crypto:term_to_ec_key(ECDHKey), - crypto:sign(ecdsa, DigestType, PlainText, ECKey); + crypto:sign(ecdsa, DigestType, DigestOrPlainText, ECKey); %% Backwards compatible sign(Digest, none, #'DSAPrivateKey'{} = Key) -> @@ -463,36 +452,28 @@ sign(Digest, none, #'DSAPrivateKey'{} = Key) -> | dsa_public_key()) -> boolean(). %% Description: Verifies a digital signature. %%-------------------------------------------------------------------- -verify({digest,_} = Digest, DigestType, Signature, - #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) -> - crypto:verify(rsa, DigestType, Digest, Signature, [Exp, Mod]); - -verify(PlainText, DigestType, Signature, +verify(DigestOrPlainText, DigestType, Signature, #'RSAPublicKey'{modulus = Mod, publicExponent = Exp}) -> - crypto:verify(rsa, DigestType, PlainText, Signature, + crypto:verify(rsa, DigestType, DigestOrPlainText, Signature, [Exp, Mod]); -verify({digest,_} = Digest, sha = DigestType, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) - when is_integer(Key), is_binary(Signature) -> - crypto:verify(dss, DigestType, Digest, Signature, [P, Q, G, Key]); - verify(Digest, DigestType, Signature, Key = #'ECPrivateKey'{}) -> - ECDHKey = ec_private_key_to_eckey(Key), + ECDHKey = format_ecdh_key(Key), ECKey = crypto:term_to_ec_key(ECDHKey), crypto:verify(ecdsa, DigestType, Digest, Signature, ECKey); -verify(Digest, DigestType, Signature, Key = {#'ECPoint'{}, _}) -> - ECDHKey = ec_public_key_to_eckey(Key), +verify(DigestOrPlaintext, DigestType, Signature, Key = {#'ECPoint'{}, _}) -> + ECDHKey = format_ecdh_key(Key), ECKey = crypto:term_to_ec_key(ECDHKey), - crypto:verify(ecdsa, DigestType, Digest, Signature, ECKey); + crypto:verify(ecdsa, DigestType, DigestOrPlaintext, Signature, ECKey); %% Backwards compatibility verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) -> verify({digest,Digest}, sha, Signature, Key); -verify(PlainText, sha = DigestType, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) - when is_integer(Key), is_binary(PlainText), is_binary(Signature) -> - crypto:verify(dss, DigestType, PlainText, Signature, [P, Q, G, Key]). +verify(DigestOrPlainText, sha = DigestType, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}}) + when is_integer(Key), is_binary(Signature) -> + crypto:verify(dss, DigestType, DigestOrPlainText, Signature, [P, Q, G, Key]). %%-------------------------------------------------------------------- -spec pkix_sign(#'OTPTBSCertificate'{}, @@ -939,40 +920,46 @@ format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, is_integer(D) -> [E, N, D]. -%% -%% Description: convert a ECPrivate key into resource Key -%%-------------------------------------------------------------------- +format_ecdh_key(#'ECPrivateKey'{privateKey = PrivKey, + parameters = Param, + publicKey = _}) -> + ECCurve = ec_curve_spec(Param), + {ECCurve, list2int(PrivKey), undefined}; + +format_ecdh_key({#'ECPoint'{point = Point}, Param}) -> + ECCurve = ec_curve_spec(Param), + {ECCurve, undefined, Point}. + +ec_curve_spec( #'OTPECParameters'{fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor }) -> + Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), + FieldId#'OTPFieldID'.parameters}, + Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, + {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; +ec_curve_spec({namedCurve, OID}) -> + pubkey_cert_records:namedCurves(OID). + +ec_key({Curve, PrivateKey, PubKey}) when is_atom(Curve) -> + #'ECPrivateKey'{version = 1, + privateKey = int2list(PrivateKey), + parameters = {namedCurve, pubkey_cert_records:namedCurves(Curve)}, + publicKey = {0, PubKey}}. + +ec_key({Curve, PrivateKey, PubKey}, _Params) when is_atom(Curve) -> + #'ECPrivateKey'{version = 1, + privateKey = int2list(PrivateKey), + parameters = {namedCurve, pubkey_cert_records:namedCurves(Curve)}, + publicKey = {0, PubKey}}; + +ec_key({_Curve, PrivateKey, PubKey}, Params) -> + #'ECPrivateKey'{version = 1, + privateKey = int2list(PrivateKey), + parameters = Params, + publicKey = {0, PubKey}}. + list2int(L) -> S = length(L) * 8, <> = erlang:iolist_to_binary(L), R. - -ec_private_key_to_eckey(#'ECPrivateKey'{privateKey = PrivKey, - parameters = Param, - publicKey = _PubKey}) -> - ECCurve = - case Param of - #'OTPECParameters'{ fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor } -> - Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), - FieldId#'OTPFieldID'.parameters}, - Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, - {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; - {namedCurve, OID} -> - pubkey_cert_records:namedCurves(OID) - end, - {ECCurve, list2int(PrivKey), undefined}. - %%{'ECKey', crypto:term_to_ec_key(Key)}. - -ec_public_key_to_eckey({#'ECPoint'{point = ECPoint}, Param}) -> - ECCurve = - case Param of - #'OTPECParameters'{ fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor } -> - Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), - FieldId#'OTPFieldID'.parameters}, - Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, - {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; - {namedCurve, OID} -> - pubkey_cert_records:namedCurves(OID) - end, - {ECCurve, undefined, ECPoint}. - %%{'ECKey', crypto:term_to_ec_key(Key)}. +int2list(I) -> + L = (length(integer_to_list(I, 16)) + 1) div 2, + binary_to_list(<>). -- cgit v1.2.3 From 3155ca5b47149a214b101f6c0b84cdcd0400a30b Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 22 Apr 2013 21:43:44 +0200 Subject: crypto, public_key & ssl: Change API to hide resource format for EC KEY --- lib/public_key/src/public_key.erl | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 06bffeea76..d1484c5b2b 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -330,10 +330,7 @@ encrypt_private(PlainText, %% Description: Generates new key(s) %%-------------------------------------------------------------------- generate_key({curve, Name}) -> - %% TODO: Better crypto API - ECDHKey = crypto:ec_key_new(Name), - crypto:ec_key_generate(ECDHKey), - Term = crypto:ec_key_to_term(ECDHKey), + Term = crypto:ecdh_generate_key(Name), ec_key(Term); generate_key(#'DHParameter'{prime = P, base = G}) -> @@ -350,13 +347,8 @@ generate_key({srp, Version, Verifier, Generator, Prime}) when is_binary(Verifier crypto:srp_generate_key(Verifier, Generator, Prime, Version); generate_key(Params) -> - %% TODO: Better crypto API - Name = ec_curve_spec(Params), - ECClntKey = crypto:ec_key_new(Name), - %% ECDHKey = format_ecdh_key(Params), - %% ECClntKey = crypto:term_to_ec_key(ECDHKey), - crypto:ec_key_generate(ECClntKey), - Term = crypto:ec_key_to_term(ECClntKey), + Curve = ec_curve_spec(Params), + Term = crypto:ecdh_generate_key(Curve), ec_key(Term, Params). %%-------------------------------------------------------------------- @@ -372,9 +364,7 @@ compute_key(PubKey, #'ECPrivateKey'{} = PrivateKey) -> compute_key(PubKey, format_ecdh_key(PrivateKey)); compute_key(#'ECPoint'{point = Point}, ECDHKeys) -> - %% TODO: Better crypto API - ECKey = crypto:term_to_ec_key(ECDHKeys), - crypto:ecdh_compute_key(ECKey, Point). + crypto:ecdh_compute_key(ECDHKeys, Point). compute_key(OthersKey, MyKey, {dh, Prime, Base}) when is_binary(OthersKey), is_binary(MyKey), @@ -439,8 +429,7 @@ sign(DigestOrPlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> sign(DigestOrPlainText, DigestType, Key = #'ECPrivateKey'{}) -> ECDHKey = format_ecdh_key(Key), - ECKey = crypto:term_to_ec_key(ECDHKey), - crypto:sign(ecdsa, DigestType, DigestOrPlainText, ECKey); + crypto:sign(ecdsa, DigestType, DigestOrPlainText, ECDHKey); %% Backwards compatible sign(Digest, none, #'DSAPrivateKey'{} = Key) -> @@ -457,15 +446,9 @@ verify(DigestOrPlainText, DigestType, Signature, crypto:verify(rsa, DigestType, DigestOrPlainText, Signature, [Exp, Mod]); -verify(Digest, DigestType, Signature, Key = #'ECPrivateKey'{}) -> - ECDHKey = format_ecdh_key(Key), - ECKey = crypto:term_to_ec_key(ECDHKey), - crypto:verify(ecdsa, DigestType, Digest, Signature, ECKey); - verify(DigestOrPlaintext, DigestType, Signature, Key = {#'ECPoint'{}, _}) -> ECDHKey = format_ecdh_key(Key), - ECKey = crypto:term_to_ec_key(ECDHKey), - crypto:verify(ecdsa, DigestType, DigestOrPlaintext, Signature, ECKey); + crypto:verify(ecdsa, DigestType, DigestOrPlaintext, Signature, ECDHKey); %% Backwards compatibility verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) -> @@ -511,12 +494,7 @@ pkix_verify(DerCert, #'RSAPublicKey'{} = RSAKey) {DigestType, PlainText, Signature} = pubkey_cert:verify_data(DerCert), verify(PlainText, DigestType, Signature, RSAKey); -pkix_verify(DerCert, #'ECPrivateKey'{} = ECKey) - when is_binary(DerCert) -> - {DigestType, PlainText, Signature} = pubkey_cert:verify_data(DerCert), - verify(PlainText, DigestType, Signature, ECKey); - -pkix_verify(DerCert, Key = {'ECKey', _}) +pkix_verify(DerCert, Key = {#'ECPoint'{}, _}) when is_binary(DerCert) -> {DigestType, PlainText, Signature} = pubkey_cert:verify_data(DerCert), verify(PlainText, DigestType, Signature, Key). -- cgit v1.2.3 From 2c1b0c61e2f6177d755e5bee9a865db646b6dca1 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 23 Apr 2013 16:51:01 +0200 Subject: crypto, public_key: Switch places of ecdh_compute_key arguments --- lib/public_key/src/public_key.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index d1484c5b2b..b11a225761 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -364,7 +364,7 @@ compute_key(PubKey, #'ECPrivateKey'{} = PrivateKey) -> compute_key(PubKey, format_ecdh_key(PrivateKey)); compute_key(#'ECPoint'{point = Point}, ECDHKeys) -> - crypto:ecdh_compute_key(ECDHKeys, Point). + crypto:ecdh_compute_key(Point, ECDHKeys). compute_key(OthersKey, MyKey, {dh, Prime, Base}) when is_binary(OthersKey), is_binary(MyKey), -- cgit v1.2.3 From 8537e256d5bb250f6e798d521deef16907a4e526 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Wed, 24 Apr 2013 09:24:02 +0200 Subject: public_key: use new crypto --- lib/public_key/src/public_key.erl | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index b11a225761..ee5c5e8552 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -331,7 +331,7 @@ encrypt_private(PlainText, %%-------------------------------------------------------------------- generate_key({curve, Name}) -> Term = crypto:ecdh_generate_key(Name), - ec_key(Term); + ec_key(Term, Name); generate_key(#'DHParameter'{prime = P, base = G}) -> crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]); @@ -916,19 +916,13 @@ ec_curve_spec( #'OTPECParameters'{fieldID = FieldId, curve = PCurve, base = Base ec_curve_spec({namedCurve, OID}) -> pubkey_cert_records:namedCurves(OID). -ec_key({Curve, PrivateKey, PubKey}) when is_atom(Curve) -> - #'ECPrivateKey'{version = 1, - privateKey = int2list(PrivateKey), - parameters = {namedCurve, pubkey_cert_records:namedCurves(Curve)}, - publicKey = {0, PubKey}}. - -ec_key({Curve, PrivateKey, PubKey}, _Params) when is_atom(Curve) -> +ec_key({PrivateKey, PubKey}, Curve) when is_atom(Curve) -> #'ECPrivateKey'{version = 1, privateKey = int2list(PrivateKey), parameters = {namedCurve, pubkey_cert_records:namedCurves(Curve)}, publicKey = {0, PubKey}}; -ec_key({_Curve, PrivateKey, PubKey}, Params) -> +ec_key({PrivateKey, PubKey}, Params) -> #'ECPrivateKey'{version = 1, privateKey = int2list(PrivateKey), parameters = Params, -- cgit v1.2.3 From abfa5825923caad09691313f39e843b70aee8f19 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Wed, 24 Apr 2013 10:51:51 +0200 Subject: ssl & public_key: API refinement Change API so public_key:generate_key/compute_key are only called with "public_key arguments" otherwhise crypto functions can be called explicitly. --- lib/public_key/src/public_key.erl | 55 +++++++++++---------------------------- 1 file changed, 15 insertions(+), 40 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index ee5c5e8552..df4f38f507 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -326,38 +326,19 @@ encrypt_private(PlainText, crypto:rsa_private_encrypt(PlainText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- --spec generate_key(#'ECPrivateKey'{} | {curve, Name ::atom()} | #'DHParameter'{}) -> {'ECKey', term()} | {binary(), binary()}. -%% Description: Generates new key(s) +-spec generate_key(#'DHParameter'{} | {namedCurve, Name ::atom()} | #'OTPECParameters'{}) -> {Public::binary(), Private::binary()}. +%% Description: Generates a new keypair %%-------------------------------------------------------------------- -generate_key({curve, Name}) -> - Term = crypto:ecdh_generate_key(Name), - ec_key(Term, Name); - generate_key(#'DHParameter'{prime = P, base = G}) -> crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]); - -generate_key({dh, Prime, Base}) when is_binary(Prime), is_binary(Base) -> - %% TODO: Is mpint could be normal binary! - crypto:dh_generate_key([Prime, Base]); - -generate_key({srp, Version, Generator, Prime}) when is_binary(Generator), is_binary(Prime) -> - crypto:srp_generate_key(Generator, Prime, Version); - -generate_key({srp, Version, Verifier, Generator, Prime}) when is_binary(Verifier), is_binary(Generator), is_binary(Prime) -> - crypto:srp_generate_key(Verifier, Generator, Prime, Version); - -generate_key(Params) -> - Curve = ec_curve_spec(Params), - Term = crypto:ecdh_generate_key(Curve), - ec_key(Term, Params). +generate_key({namedCurve, _} = Params) -> + ec_generate_key(Params); +generate_key(#'OTPECParameters'{} = Params) -> + ec_generate_key(Params). %%-------------------------------------------------------------------- --spec compute_key(#'ECPoint'{}, #'ECPrivateKey'{} | crypto:ecdh_key()) -> binary(). --spec compute_key(OthersKey ::binary(), MyKey::binary() | {binary(), binary()}, - {dh, binary(), binary()} | - {srp,'3'|'6'| '6a' , binary(), binary()} | - {srp, string(), string(), binary(), '3'|'6'| '6a', binary(), binary()}) - -> binary(). +-spec compute_key(#'ECPoint'{} , #'ECPrivateKey'{}) -> binary(). +-spec compute_key(OthersKey ::binary(), MyKey::binary(), #'DHParameter'{}) -> binary(). %% Description: Compute shared secret %%-------------------------------------------------------------------- compute_key(PubKey, #'ECPrivateKey'{} = PrivateKey) -> @@ -366,19 +347,8 @@ compute_key(PubKey, #'ECPrivateKey'{} = PrivateKey) -> compute_key(#'ECPoint'{point = Point}, ECDHKeys) -> crypto:ecdh_compute_key(Point, ECDHKeys). -compute_key(OthersKey, MyKey, {dh, Prime, Base}) when is_binary(OthersKey), - is_binary(MyKey), - is_binary(Prime), - is_binary(Base) -> - %% TODO: Is mpint could be binary! - crypto:dh_compute_key(OthersKey, MyKey, [Prime, Base]); - -compute_key(ClientPub, {ServerPub, ServerPriv}, {srp, Version, Verifier, Prime}) -> - crypto:srp_compute_key(Verifier, Prime, ClientPub, ServerPub, ServerPriv, Version); - -compute_key(ServerPub, {ClientPub, ClientPriv}, {srp, Username, Password, Salt, Version, Prime, Generator}) -> - DerivedKey = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]), - crypto:srp_compute_key(DerivedKey, Prime, Generator, ClientPub, ClientPriv, ServerPub, Version). +compute_key(PubKey, PrivKey, #'DHParameter'{prime = P, base = G}) -> + crypto:dh_compute_key(PubKey, PrivKey, [crypto:mpint(P), crypto:mpint(G)]). %%-------------------------------------------------------------------- -spec pkix_sign_types(SignatureAlg::oid()) -> @@ -898,6 +868,11 @@ format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, is_integer(D) -> [E, N, D]. +ec_generate_key(Params) -> + Curve = ec_curve_spec(Params), + Term = crypto:ecdh_generate_key(Curve), + ec_key(Term, Params). + format_ecdh_key(#'ECPrivateKey'{privateKey = PrivKey, parameters = Param, publicKey = _}) -> -- cgit v1.2.3 From dad86c51e920d015da390ec6bef3da24924fa063 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Thu, 25 Apr 2013 11:04:36 +0200 Subject: ssl, public_key, crypto: General generate_key and compute_key functions --- lib/public_key/src/public_key.erl | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index df4f38f507..3497018a88 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -330,7 +330,7 @@ encrypt_private(PlainText, %% Description: Generates a new keypair %%-------------------------------------------------------------------- generate_key(#'DHParameter'{prime = P, base = G}) -> - crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]); + crypto:generate_key(dh, [P, G]); generate_key({namedCurve, _} = Params) -> ec_generate_key(Params); generate_key(#'OTPECParameters'{} = Params) -> @@ -341,14 +341,13 @@ generate_key(#'OTPECParameters'{} = Params) -> -spec compute_key(OthersKey ::binary(), MyKey::binary(), #'DHParameter'{}) -> binary(). %% Description: Compute shared secret %%-------------------------------------------------------------------- -compute_key(PubKey, #'ECPrivateKey'{} = PrivateKey) -> - compute_key(PubKey, format_ecdh_key(PrivateKey)); - -compute_key(#'ECPoint'{point = Point}, ECDHKeys) -> - crypto:ecdh_compute_key(Point, ECDHKeys). +compute_key(#'ECPoint'{point = Point}, #'ECPrivateKey'{privateKey = PrivKey, + parameters = Param}) -> + ECCurve = ec_curve_spec(Param), + crypto:compute_key(ecdh, Point, list2int(PrivKey), ECCurve). compute_key(PubKey, PrivKey, #'DHParameter'{prime = P, base = G}) -> - crypto:dh_compute_key(PubKey, PrivKey, [crypto:mpint(P), crypto:mpint(G)]). + crypto:compute_key(dh, PubKey, PrivKey, [P, G]). %%-------------------------------------------------------------------- -spec pkix_sign_types(SignatureAlg::oid()) -> @@ -741,10 +740,6 @@ validate(Cert, #path_validation_state{working_issuer_name = Issuer, pubkey_cert:prepare_for_next_cert(OtpCert, ValidationState). -sized_binary(Binary) -> - Size = size(Binary), - <>. - otp_cert(Der) when is_binary(Der) -> pkix_decode_cert(Der, otp); otp_cert(#'OTPCertificate'{} =Cert) -> @@ -870,7 +865,7 @@ format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, ec_generate_key(Params) -> Curve = ec_curve_spec(Params), - Term = crypto:ecdh_generate_key(Curve), + Term = crypto:generate_key(ecdh, Curve), ec_key(Term, Params). format_ecdh_key(#'ECPrivateKey'{privateKey = PrivKey, -- cgit v1.2.3 From badb8f14e9829ce0a797b56702997aa355cdd9ba Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Thu, 25 Apr 2013 14:51:19 +0200 Subject: ssl, crypto: Eliminate remaining mpint and EC resource key from API --- lib/public_key/src/public_key.erl | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 3497018a88..a8fe9213ea 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -326,7 +326,9 @@ encrypt_private(PlainText, crypto:rsa_private_encrypt(PlainText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- --spec generate_key(#'DHParameter'{} | {namedCurve, Name ::atom()} | #'OTPECParameters'{}) -> {Public::binary(), Private::binary()}. +-spec generate_key(#'DHParameter'{} | {namedCurve, Name ::atom()} | + #'OTPECParameters'{}) -> {Public::binary(), Private::binary()} | + #'ECPrivateKey'{}. %% Description: Generates a new keypair %%-------------------------------------------------------------------- generate_key(#'DHParameter'{prime = P, base = G}) -> @@ -396,9 +398,10 @@ sign(DigestOrPlainText, DigestType, Key = #'RSAPrivateKey'{}) -> sign(DigestOrPlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) -> crypto:sign(dss, sha, DigestOrPlainText, [P, Q, G, X]); -sign(DigestOrPlainText, DigestType, Key = #'ECPrivateKey'{}) -> - ECDHKey = format_ecdh_key(Key), - crypto:sign(ecdsa, DigestType, DigestOrPlainText, ECDHKey); +sign(DigestOrPlainText, DigestType, #'ECPrivateKey'{privateKey = PrivKey, + parameters = Param}) -> + ECCurve = ec_curve_spec(Param), + crypto:sign(ecdsa, DigestType, DigestOrPlainText, [list2int(PrivKey), ECCurve]); %% Backwards compatible sign(Digest, none, #'DSAPrivateKey'{} = Key) -> @@ -415,9 +418,9 @@ verify(DigestOrPlainText, DigestType, Signature, crypto:verify(rsa, DigestType, DigestOrPlainText, Signature, [Exp, Mod]); -verify(DigestOrPlaintext, DigestType, Signature, Key = {#'ECPoint'{}, _}) -> - ECDHKey = format_ecdh_key(Key), - crypto:verify(ecdsa, DigestType, DigestOrPlaintext, Signature, ECDHKey); +verify(DigestOrPlaintext, DigestType, Signature, {#'ECPoint'{point = Point}, Param}) -> + ECCurve = ec_curve_spec(Param), + crypto:verify(ecdsa, DigestType, DigestOrPlaintext, Signature, [Point, ECCurve]); %% Backwards compatibility verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) -> @@ -868,20 +871,10 @@ ec_generate_key(Params) -> Term = crypto:generate_key(ecdh, Curve), ec_key(Term, Params). -format_ecdh_key(#'ECPrivateKey'{privateKey = PrivKey, - parameters = Param, - publicKey = _}) -> - ECCurve = ec_curve_spec(Param), - {ECCurve, list2int(PrivKey), undefined}; - -format_ecdh_key({#'ECPoint'{point = Point}, Param}) -> - ECCurve = ec_curve_spec(Param), - {ECCurve, undefined, Point}. - ec_curve_spec( #'OTPECParameters'{fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor }) -> Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), FieldId#'OTPFieldID'.parameters}, - Curve = {list2int(PCurve#'Curve'.a), list2int(PCurve#'Curve'.b), none}, + Curve = {erlang:list_to_binary(PCurve#'Curve'.a), erlang:list_to_binary(PCurve#'Curve'.b), none}, {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; ec_curve_spec({namedCurve, OID}) -> pubkey_cert_records:namedCurves(OID). -- cgit v1.2.3 From 7c901c92f5936ca2f212300d2f13f899b7a222e0 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Fri, 26 Apr 2013 18:08:48 +0200 Subject: crypto: Deprecate functions, update doc and specs --- lib/public_key/doc/src/public_key.xml | 16 +++++++++------- lib/public_key/include/public_key.hrl | 4 +++- lib/public_key/src/public_key.erl | 21 ++++++++------------- lib/public_key/test/pkits_SUITE.erl | 11 +++++------ lib/public_key/test/public_key_SUITE.erl | 2 +- 5 files changed, 26 insertions(+), 28 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index 9cad17e4c3..45aaf21b80 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -100,8 +100,10 @@

dsa_public_key() = {integer(), #'Dss-Parms'{}}

dsa_private_key() = #'DSAPrivateKey'{}

+ +

ec_public_key() = {#'ECPoint'{}, #'OTPEcpkParameters'{} | {namedCurve, oid()}}

-

ec_key() = {'ECKey', Key}

+

ec_private_key() = #'ECPrivateKey'{}

public_crypt_options() = [{rsa_pad, rsa_padding()}].

@@ -112,7 +114,7 @@

dss_digest_type() = 'sha'

-

ecdsa_digest_type() = 'sha'

+

ecdsa_digest_type() = 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'

crl_reason() = unspecified | keyCompromise | cACompromise | affiliationChanged | superseded | cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise

@@ -534,7 +536,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} | signed or it is the hashed value of "plain text" i.e. the digest. DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() - Key = rsa_private_key() | dsa_private_key() | ec_key() + Key = rsa_private_key() | dsa_private_key() | ec_private_key()

Creates a digital signature.

@@ -599,10 +601,10 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} | or it is the hashed value of "plain text" i.e. the digest. DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() Signature = binary() - Key = rsa_public_key() | dsa_public_key() | ec_key() - - -

Verifies a digital signature

+ Key = rsa_public_key() | dsa_public_key() | ec_public_key() + + +

Verifies a digital signature

diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl index 976104fe6c..363305957c 100644 --- a/lib/public_key/include/public_key.hrl +++ b/lib/public_key/include/public_key.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -93,6 +93,8 @@ -type rsa_private_key() :: #'RSAPrivateKey'{}. -type dsa_private_key() :: #'DSAPrivateKey'{}. -type dsa_public_key() :: {integer(), #'Dss-Parms'{}}. +-type ec_public_key() :: {#'ECPoint'{},{namedCurve, Oid::tuple()} | #'OTPECParameters'{}}. +-type ec_private_key() :: #'ECPrivateKey'{}. -type der_encoded() :: binary(). -type decrypt_der() :: binary(). -type pki_asn1_type() :: 'Certificate' | 'RSAPrivateKey' | 'RSAPublicKey' diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index a8fe9213ea..96eaacf60e 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -54,6 +54,7 @@ -type public_crypt_options() :: [{rsa_pad, rsa_padding()}]. -type rsa_digest_type() :: 'md5' | 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'. -type dss_digest_type() :: 'none' | 'sha'. %% None is for backwards compatibility +-type ecdsa_digest_type() :: 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'. -type crl_reason() :: unspecified | keyCompromise | cACompromise | affiliationChanged | superseded | cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise. -type oid() :: tuple(). @@ -97,7 +98,7 @@ pem_entry_decode({'SubjectPublicKeyInfo', Der, _}) -> 'DSAPublicKey' -> {params, DssParams} = der_decode('DSAParams', Params), {der_decode(KeyType, Key0), DssParams}; - 'ECPrivateKey' -> + 'ECPoint' -> der_decode(KeyType, Key0) end; pem_entry_decode({Asn1Type, Der, not_encrypted}) when is_atom(Asn1Type), @@ -355,7 +356,7 @@ compute_key(PubKey, PrivKey, #'DHParameter'{prime = P, base = G}) -> -spec pkix_sign_types(SignatureAlg::oid()) -> %% Relevant dsa digest type is subpart of rsa digest type { DigestType :: rsa_digest_type(), - SignatureType :: rsa | dsa + SignatureType :: rsa | dsa | ecdsa }. %% Description: %%-------------------------------------------------------------------- @@ -387,9 +388,9 @@ pkix_sign_types(?'ecdsa-with-SHA512') -> {sha512, ecdsa}. %%-------------------------------------------------------------------- --spec sign(binary() | {digest, binary()}, rsa_digest_type() | dss_digest_type(), +-spec sign(binary() | {digest, binary()}, rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), rsa_private_key() | - dsa_private_key()) -> Signature :: binary(). + dsa_private_key() | ec_private_key()) -> Signature :: binary(). %% Description: Create digital signature. %%-------------------------------------------------------------------- sign(DigestOrPlainText, DigestType, Key = #'RSAPrivateKey'{}) -> @@ -408,9 +409,9 @@ sign(Digest, none, #'DSAPrivateKey'{} = Key) -> sign({digest,Digest}, sha, Key). %%-------------------------------------------------------------------- --spec verify(binary() | {digest, binary()}, rsa_digest_type() | dss_digest_type(), +-spec verify(binary() | {digest, binary()}, rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), Signature :: binary(), rsa_public_key() - | dsa_public_key()) -> boolean(). + | dsa_public_key() | ec_public_key()) -> boolean(). %% Description: Verifies a digital signature. %%-------------------------------------------------------------------- verify(DigestOrPlainText, DigestType, Signature, @@ -452,7 +453,7 @@ pkix_sign(#'OTPTBSCertificate'{signature = %%-------------------------------------------------------------------- -spec pkix_verify(Cert::binary(), rsa_public_key()| - dsa_public_key()) -> boolean(). + dsa_public_key() | ec_public_key()) -> boolean(). %% %% Description: Verify pkix x.509 certificate signature. %%-------------------------------------------------------------------- @@ -879,12 +880,6 @@ ec_curve_spec( #'OTPECParameters'{fieldID = FieldId, curve = PCurve, base = Base ec_curve_spec({namedCurve, OID}) -> pubkey_cert_records:namedCurves(OID). -ec_key({PrivateKey, PubKey}, Curve) when is_atom(Curve) -> - #'ECPrivateKey'{version = 1, - privateKey = int2list(PrivateKey), - parameters = {namedCurve, pubkey_cert_records:namedCurves(Curve)}, - publicKey = {0, PubKey}}; - ec_key({PrivateKey, PubKey}, Params) -> #'ECPrivateKey'{version = 1, privateKey = int2list(PrivateKey), diff --git a/lib/public_key/test/pkits_SUITE.erl b/lib/public_key/test/pkits_SUITE.erl index d901adaadd..8cdf0aaae3 100644 --- a/lib/public_key/test/pkits_SUITE.erl +++ b/lib/public_key/test/pkits_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -758,11 +758,10 @@ warning(Format, Args, File0, Line) -> io:format("~s(~p): Warning "++Format, [File,Line|Args]). crypto_support_check(Config) -> - try crypto:sha256(<<"Test">>) of - _ -> - Config - catch error:notsup -> - crypto:stop(), + case proplists:get_bool(sha256, crypto:algorithms()) of + true -> + Config; + false -> {skip, "To old version of openssl"} end. diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index 0de80edeac..5a64140c67 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -551,7 +551,7 @@ dsa_sign_verify(Config) when is_list(Config) -> false = public_key:verify(Msg, sha, <<1:8, DSASign/binary>>, {DSAPublicKey, DSAParams}), - Digest = crypto:sha(Msg), + Digest = crypto:hash(sha,Msg), DigestSign = public_key:sign(Digest, none, DSAPrivateKey), true = public_key:verify(Digest, none, DigestSign, {DSAPublicKey, DSAParams}), <<_:8, RestDigest/binary>> = Digest, -- cgit v1.2.3 From b968404bfb277c64f3ab040fd5921f8583443c6f Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Tue, 30 Apr 2013 18:29:26 +0200 Subject: ssl & public_key: Use new crypto API functions --- lib/public_key/src/public_key.erl | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 96eaacf60e..f9042d5349 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -258,7 +258,7 @@ decrypt_private(CipherText, when is_binary(CipherText), is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_decrypt(CipherText, format_rsa_private_key(Key), Padding). + crypto:private_decrypt(rsa, CipherText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- -spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key()) -> @@ -324,7 +324,7 @@ encrypt_private(PlainText, is_integer(N), is_integer(E), is_integer(D), is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_encrypt(PlainText, format_rsa_private_key(Key), Padding). + crypto:private_encrypt(rsa, PlainText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- -spec generate_key(#'DHParameter'{} | {namedCurve, Name ::atom()} | @@ -652,13 +652,11 @@ do_pem_entry_decode({Asn1Type,_, _} = PemEntry, Password) -> encrypt_public(PlainText, N, E, Options)-> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_public_encrypt(PlainText, [E,N], - Padding). + crypto:public_encrypt(rsa, PlainText, [E,N], Padding). -decrypt_public(CipherText, N,E, Options) -> +decrypt_public(CipherText, N,E, Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_public_decrypt(CipherText,[E, N], - Padding). + crypto:public_decrypt(rsa, CipherText,[E, N], Padding). path_validation([], #path_validation_state{working_public_key_algorithm = Algorithm, -- cgit v1.2.3 From a9add4e3d878bbd339fc2bb36e97d1053318b4e6 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Thu, 2 May 2013 14:30:39 +0200 Subject: public_key: Add new API functions to the documentation --- lib/public_key/doc/src/public_key.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'lib/public_key') diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index 45aaf21b80..ffea387404 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -153,6 +153,19 @@ + + compute_key(OthersKey, MyKey)-> + compute_key(OthersKey, MyKey, Params)-> + Compute shared secret + + OthersKey = #'ECPoint'{} | binary(), MyKey = #'ECPrivateKey'{} | binary() + Params = #'DHParameter'{} + + +

Compute shared secret

+
+
+ decrypt_private(CipherText, Key) -> binary() decrypt_private(CipherText, Key, Options) -> binary() @@ -210,6 +223,17 @@
+ + generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{} + Generates a new keypair + + Params = #'DHParameter'{} | {namedCurve, oid()} | #'OTPECParameters'{} + + +

Generates a new keypair

+
+
+ pem_decode(PemBin) -> [pem_entry()] Decode PEM binary data and return -- cgit v1.2.3 From 01f5de8764b200bdd0d5e4ff69fba4523b3c2c7c Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Fri, 3 May 2013 12:28:39 +0200 Subject: ssl & public_key: Use standard name --- lib/public_key/asn1/ECPrivateKey.asn1 | 6 +++--- lib/public_key/asn1/OTP-PKIX.asn1 | 20 ++------------------ lib/public_key/doc/src/public_key.xml | 6 +++--- lib/public_key/include/public_key.hrl | 2 +- lib/public_key/src/public_key.erl | 10 +++++----- 5 files changed, 14 insertions(+), 30 deletions(-) (limited to 'lib/public_key') diff --git a/lib/public_key/asn1/ECPrivateKey.asn1 b/lib/public_key/asn1/ECPrivateKey.asn1 index e8607c4f7b..a20fa4009c 100644 --- a/lib/public_key/asn1/ECPrivateKey.asn1 +++ b/lib/public_key/asn1/ECPrivateKey.asn1 @@ -12,13 +12,13 @@ IMPORTS -- FROM New PKIX ASN.1 [RFC5912] -OTPEcpkParameters FROM OTP-PKIX; +EcpkParameters FROM PKIX1Algorithms88; ECPrivateKey ::= SEQUENCE { version INTEGER, privateKey OCTET STRING, - parameters [0] OTPEcpkParameters OPTIONAL, + parameters [0] EcpkParameters OPTIONAL, publicKey [1] BIT STRING OPTIONAL } -END \ No newline at end of file +END diff --git a/lib/public_key/asn1/OTP-PKIX.asn1 b/lib/public_key/asn1/OTP-PKIX.asn1 index 4a9d401345..911a156d6c 100644 --- a/lib/public_key/asn1/OTP-PKIX.asn1 +++ b/lib/public_key/asn1/OTP-PKIX.asn1 @@ -103,7 +103,7 @@ IMPORTS md5WithRSAEncryption, sha1WithRSAEncryption, rsaEncryption, RSAPublicKey, - dhpublicnumber, DomainParameters, DHPublicKey, + dhpublicnumber, DomainParameters, DHPublicKey, id-keyExchangeAlgorithm, KEA-Parms-Id, --KEA-PublicKey, ecdsa-with-SHA1, ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, ecdsa-with-SHA512, @@ -112,7 +112,7 @@ IMPORTS gnBasis, tpBasis, Trinomial, ppBasis, Pentanomial, - id-ecPublicKey, EcpkParameters, ECPoint + id-ecPublicKey, EcpkParameters, ECParameters, ECPoint FROM PKIX1Algorithms88 { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-algorithms(17) } @@ -510,22 +510,6 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { ID ppBasis TYPE Pentanomial } - -- Elliptic Curve parameters may be specified explicitly, - -- specified implicitly through a "named curve", or - -- inherited from the CA - - OTPEcpkParameters ::= CHOICE { - ecParameters OTPECParameters, - namedCurve OBJECT IDENTIFIER, - implicitlyCA NULL } - - OTPECParameters ::= SEQUENCE { -- Elliptic curve parameters - version ECPVer, - fieldID OTPFieldID, - curve Curve, - base ECPoint, -- Base point G - order INTEGER, -- Order n of the base point - cofactor INTEGER OPTIONAL } -- The integer h = #E(Fq)/n -- SubjectPublicKeyInfo.algorithm diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index ffea387404..10c95a39ac 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -85,7 +85,7 @@

pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey' | 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' | 'SubjectPublicKeyInfo' | 'PrivateKeyInfo' | 'CertificationRequest' | 'ECPrivateKey'| - 'OTPEcpkParameters'

+ 'EcpkParameters'

pem_entry () = {pki_asn1_type(), binary(), %% DER or encrypted DER not_encrypted | cipher_info()}

@@ -101,7 +101,7 @@

dsa_private_key() = #'DSAPrivateKey'{}

-

ec_public_key() = {#'ECPoint'{}, #'OTPEcpkParameters'{} | {namedCurve, oid()}}

+

ec_public_key() = {#'ECPoint'{}, #'EcpkParameters'{} | {namedCurve, oid()}}

ec_private_key() = #'ECPrivateKey'{}

@@ -227,7 +227,7 @@ generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{} Generates a new keypair - Params = #'DHParameter'{} | {namedCurve, oid()} | #'OTPECParameters'{} + Params = #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{}

Generates a new keypair

diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl index 363305957c..1e882e76ee 100644 --- a/lib/public_key/include/public_key.hrl +++ b/lib/public_key/include/public_key.hrl @@ -93,7 +93,7 @@ -type rsa_private_key() :: #'RSAPrivateKey'{}. -type dsa_private_key() :: #'DSAPrivateKey'{}. -type dsa_public_key() :: {integer(), #'Dss-Parms'{}}. --type ec_public_key() :: {#'ECPoint'{},{namedCurve, Oid::tuple()} | #'OTPECParameters'{}}. +-type ec_public_key() :: {#'ECPoint'{},{namedCurve, Oid::tuple()} | #'ECParameters'{}}. -type ec_private_key() :: #'ECPrivateKey'{}. -type der_encoded() :: binary(). -type decrypt_der() :: binary(). diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index f9042d5349..648dba3d5a 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -328,7 +328,7 @@ encrypt_private(PlainText, %%-------------------------------------------------------------------- -spec generate_key(#'DHParameter'{} | {namedCurve, Name ::atom()} | - #'OTPECParameters'{}) -> {Public::binary(), Private::binary()} | + #'ECParameters'{}) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{}. %% Description: Generates a new keypair %%-------------------------------------------------------------------- @@ -336,7 +336,7 @@ generate_key(#'DHParameter'{prime = P, base = G}) -> crypto:generate_key(dh, [P, G]); generate_key({namedCurve, _} = Params) -> ec_generate_key(Params); -generate_key(#'OTPECParameters'{} = Params) -> +generate_key(#'ECParameters'{} = Params) -> ec_generate_key(Params). %%-------------------------------------------------------------------- @@ -870,9 +870,9 @@ ec_generate_key(Params) -> Term = crypto:generate_key(ecdh, Curve), ec_key(Term, Params). -ec_curve_spec( #'OTPECParameters'{fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor }) -> - Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'OTPFieldID'.fieldType), - FieldId#'OTPFieldID'.parameters}, +ec_curve_spec( #'ECParameters'{fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor }) -> + Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'FieldID'.fieldType), + FieldId#'FieldID'.parameters}, Curve = {erlang:list_to_binary(PCurve#'Curve'.a), erlang:list_to_binary(PCurve#'Curve'.b), none}, {Field, Curve, erlang:list_to_binary(Base), Order, CoFactor}; ec_curve_spec({namedCurve, OID}) -> -- cgit v1.2.3