aboutsummaryrefslogtreecommitdiffstats
path: root/lib/public_key
diff options
context:
space:
mode:
Diffstat (limited to 'lib/public_key')
-rw-r--r--lib/public_key/asn1/ECPrivateKey.asn124
-rw-r--r--lib/public_key/asn1/OTP-PKIX.asn152
-rw-r--r--lib/public_key/asn1/OTP-PUB-KEY.set.asn1
-rw-r--r--lib/public_key/asn1/PKCS-1.asn136
-rw-r--r--lib/public_key/asn1/PKIX1Algorithms88.asn1121
-rw-r--r--lib/public_key/doc/src/cert_records.xml27
-rw-r--r--lib/public_key/doc/src/public_key.xml68
-rw-r--r--lib/public_key/include/public_key.hrl8
-rw-r--r--lib/public_key/src/pubkey_cert.erl22
-rw-r--r--lib/public_key/src/pubkey_cert_records.erl88
-rw-r--r--lib/public_key/src/pubkey_crl.erl4
-rw-r--r--lib/public_key/src/pubkey_pem.erl16
-rw-r--r--lib/public_key/src/public_key.erl221
-rw-r--r--lib/public_key/test/erl_make_certs.erl71
-rw-r--r--lib/public_key/test/pkits_SUITE.erl11
-rw-r--r--lib/public_key/test/public_key_SUITE.erl32
-rw-r--r--lib/public_key/test/public_key_SUITE_data/dsa_ISO.pem24
-rw-r--r--lib/public_key/test/public_key_SUITE_data/rsa_ISO.pem14
18 files changed, 660 insertions, 180 deletions
diff --git a/lib/public_key/asn1/ECPrivateKey.asn1 b/lib/public_key/asn1/ECPrivateKey.asn1
new file mode 100644
index 0000000000..a20fa4009c
--- /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]
+
+EcpkParameters FROM PKIX1Algorithms88;
+
+ECPrivateKey ::= SEQUENCE {
+ version INTEGER,
+ privateKey OCTET STRING,
+ parameters [0] EcpkParameters OPTIONAL,
+ publicKey [1] BIT STRING OPTIONAL
+}
+
+END
diff --git a/lib/public_key/asn1/OTP-PKIX.asn1 b/lib/public_key/asn1/OTP-PKIX.asn1
index 4f20208bce..911a156d6c 100644
--- a/lib/public_key/asn1/OTP-PKIX.asn1
+++ b/lib/public_key/asn1/OTP-PKIX.asn1
@@ -97,25 +97,25 @@ IMPORTS
id-pkix1-implicit(19) }
--Keys and Signatures
- id-dsa, Dss-Parms, DSAPublicKey,
- id-dsa-with-sha1,
- md2WithRSAEncryption,
+ id-dsa, Dss-Parms, DSAPublicKey,
+ id-dsa-with-sha1, id-dsaWithSHA1,
+ md2WithRSAEncryption,
md5WithRSAEncryption,
sha1WithRSAEncryption,
rsaEncryption, RSAPublicKey,
- dhpublicnumber, DomainParameters, DHPublicKey,
+ 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,
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) }
-
md2WithRSAEncryption,
md5WithRSAEncryption,
sha1WithRSAEncryption,
@@ -316,16 +316,20 @@ PublicKeyAlgorithm ::= SEQUENCE {
OPTIONAL }
SupportedSignatureAlgorithms SIGNATURE-ALGORITHM-CLASS ::= {
- dsa-with-sha1 | md2-with-rsa-encryption |
- md5-with-rsa-encryption | sha1-with-rsa-encryption |
+ dsa-with-sha1 | dsaWithSHA1 | md2-with-rsa-encryption |
+ md5-with-rsa-encryption | sha1-with-rsa-encryption | sha-1with-rsa-encryption |
sha224-with-rsa-encryption |
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 }
+ dsa | rsa-encryption | dh | kea | ec-public-key }
-- DSA Keys and Signatures
@@ -349,6 +353,11 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= {
ID id-dsa-with-sha1
TYPE DSAParams }
+
+ dsaWithSHA1 SIGNATURE-ALGORITHM-CLASS ::= {
+ ID id-dsaWithSHA1
+ TYPE DSAParams }
+
--
-- RSA Keys and Signatures
--
@@ -367,6 +376,10 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= {
ID sha1WithRSAEncryption
TYPE NULL }
+ sha-1with-rsa-encryption SIGNATURE-ALGORITHM-CLASS ::= {
+ ID sha-1WithRSAEncryption
+ TYPE NULL }
+
sha224-with-rsa-encryption SIGNATURE-ALGORITHM-CLASS ::= {
ID sha224WithRSAEncryption
TYPE NULL }
@@ -431,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 }
@@ -481,6 +510,7 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= {
ID ppBasis
TYPE Pentanomial }
+
-- 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 c83289e779..117eacd8ad 100644
--- a/lib/public_key/asn1/PKCS-1.asn1
+++ b/lib/public_key/asn1/PKCS-1.asn1
@@ -35,7 +35,9 @@ sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 }
-
+-- ISO oid - equvivalent to sha1WithRSAEncryption
+sha-1WithRSAEncryption OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) sha-1WithRSAEncryption(29)}
id-sha1 OBJECT IDENTIFIER ::= {
iso(1) identified-organization(3) oiw(14) secsig(3)
@@ -50,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 f895b6d0cd..6cc6745af6 100644
--- a/lib/public_key/asn1/PKIX1Algorithms88.asn1
+++ b/lib/public_key/asn1/PKIX1Algorithms88.asn1
@@ -35,6 +35,9 @@
id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 }
+ id-dsaWithSHA1 OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) dsaWithSHA1(27)
+ }
-- encoding for DSA signature generated with SHA-1 hash
Dss-Sig-Value ::= SEQUENCE {
@@ -95,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
@@ -196,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/cert_records.xml b/lib/public_key/doc/src/cert_records.xml
index ac4b4e4489..c9249d40c3 100644
--- a/lib/public_key/doc/src/cert_records.xml
+++ b/lib/public_key/doc/src/cert_records.xml
@@ -60,9 +60,6 @@
marker="public_key">public key reference manual </seealso> or
follows here.</p>
- <p><c>oid() - a tuple of integers
- as generated by the ASN1 compiler.</c></p>
-
<p><c>time() = uct_time() | general_time()</c></p>
<p><c>uct_time() = {utcTime, "YYMMDDHHMMSSZ"} </c></p>
@@ -158,6 +155,9 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
<cell align="left" valign="middle">id-dsa-with-sha1</cell>
</row>
<row>
+ <cell align="left" valign="middle">id-dsaWithSHA1 (ISO alt oid to above)</cell>
+ </row>
+ <row>
<cell align="left" valign="middle">md2WithRSAEncryption</cell>
</row>
<row>
@@ -166,9 +166,21 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
<row>
<cell align="left" valign="middle">sha1WithRSAEncryption</cell>
</row>
+ <row>
+ <cell align="left" valign="middle">sha-1WithRSAEncryption (ISO alt oid to above)</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">sha224WithRSAEncryption</cell>
+ </row>
<row>
- <cell align="left" valign="middle">ecdsa-with-SHA1</cell>
+ <cell align="left" valign="middle">sha256WithRSAEncryption</cell>
</row>
+ <row>
+ <cell align="left" valign="middle">sha512WithRSAEncryption</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">ecdsa-with-SHA1</cell>
+ </row>
<tcaption>Signature algorithm oids </tcaption>
</table>
@@ -276,15 +288,14 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
<cell align="left" valign="middle">dhpublicnumber</cell>
</row>
<row>
- <cell align="left" valign="middle">ecdsa-with-SHA1</cell>
- </row>
- <row>
<cell align="left" valign="middle">id-keyExchangeAlgorithm</cell>
</row>
+ <row>
+ <cell align="left" valign="middle">id-ecPublicKey</cell>
+ </row>
<tcaption>Public key algorithm oids </tcaption>
</table>
-
<code>
#'Extension'{
extnID, % id_extensions() | oid()
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index 5864de2d57..10c95a39ac 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -48,7 +48,7 @@
<item>Supports <url href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280 </url> -
Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile </item>
<item>Supports <url href="http://www.rsa.com/rsalabs/node.asp?id=2125"> PKCS-1 </url> - RSA Cryptography Standard </item>
- <item>Supports <url href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf"> DSA</url>- Digital Signature Algorithm</item>
+ <item>Supports <url href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf"> DSS</url>- Digital Signature Standard (DSA - Digital Signature Algorithm)</item>
<item>Supports <url href="http://www.rsa.com/rsalabs/node.asp?id=2126"> PKCS-3 </url> - Diffie-Hellman Key Agreement Standard </item>
<item>Supports <url href="http://www.rsa.com/rsalabs/node.asp?id=2127"> PKCS-5</url> - Password-Based Cryptography Standard </item>
<item>Supports <url href="http://www.rsa.com/rsalabs/node.asp?id=2130"> PKCS-8</url> - Private-Key Information Syntax Standard</item>
@@ -72,8 +72,10 @@
<code> -include_lib("public_key/include/public_key.hrl"). </code>
- <p><em>Data Types </em></p>
+ <p><em>Data Types </em></p>
+ <p><code>oid() - a tuple of integers as generated by the ASN1 compiler.</code></p>
+
<p><code>boolean() = true | false</code></p>
<p><code>string() = [bytes()]</code></p>
@@ -82,7 +84,8 @@
<p><code>pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey' |
'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' | 'SubjectPublicKeyInfo' |
- 'PrivateKeyInfo' | 'CertificationRequest'</code></p>
+ 'PrivateKeyInfo' | 'CertificationRequest' | 'ECPrivateKey'|
+ 'EcpkParameters'</code></p>
<p><code>pem_entry () = {pki_asn1_type(), binary(), %% DER or encrypted DER
not_encrypted | cipher_info()} </code></p>
@@ -97,7 +100,11 @@
<p><code>dsa_public_key() = {integer(), #'Dss-Parms'{}} </code></p>
<p><code>dsa_private_key() = #'DSAPrivateKey'{}</code></p>
+
+ <p><code>ec_public_key() = {#'ECPoint'{}, #'EcpkParameters'{} | {namedCurve, oid()}} </code></p>
+ <p><code>ec_private_key() = #'ECPrivateKey'{}</code></p>
+
<p><code> public_crypt_options() = [{rsa_pad, rsa_padding()}]. </code></p>
<p><code> rsa_padding() = 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding'
@@ -107,6 +114,8 @@
<p><code> dss_digest_type() = 'sha' </code></p>
+ <p><code> ecdsa_digest_type() = 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512' </code></p>
+
<p><code> crl_reason() = unspecified | keyCompromise | cACompromise | affiliationChanged | superseded | cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise
</code></p>
@@ -145,6 +154,19 @@
<funcs>
<func>
+ <name> compute_key(OthersKey, MyKey)-></name>
+ <name> compute_key(OthersKey, MyKey, Params)-></name>
+ <fsummary> Compute shared secret</fsummary>
+ <type>
+ <v>OthersKey = #'ECPoint'{} | binary(), MyKey = #'ECPrivateKey'{} | binary()</v>
+ <v>Params = #'DHParameter'{}</v>
+ </type>
+ <desc>
+ <p> Compute shared secret </p>
+ </desc>
+ </func>
+
+ <func>
<name>decrypt_private(CipherText, Key) -> binary()</name>
<name>decrypt_private(CipherText, Key, Options) -> binary()</name>
<fsummary>Public key decryption.</fsummary>
@@ -202,6 +224,17 @@
</func>
<func>
+ <name>generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{} </name>
+ <fsummary>Generates a new keypair</fsummary>
+ <type>
+ <v> Params = #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{} </v>
+ </type>
+ <desc>
+ <p>Generates a new keypair</p>
+ </desc>
+ </func>
+
+ <func>
<name>pem_decode(PemBin) -> [pem_entry()]</name>
<fsummary>Decode PEM binary data and return
entries as ASN.1 DER encoded entities. </fsummary>
@@ -491,6 +524,21 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
</desc>
</func>
+ <func>
+ <name>pkix_sign_types(AlgorithmId) -> {DigestType, SignatureType}</name>
+ <fsummary>Translates signature algorithm oid to erlang digest and signature algorithm types.</fsummary>
+ <type>
+ <v>AlgorithmId = oid()</v>
+ <d>Signature oid from a certificate or a certificate revocation list</d>
+ <v>DigestType = rsa_digest_type() | dss_digest_type() </v>
+ <v>SignatureType = rsa | dsa</v>
+ </type>
+ <desc>
+ <p>Translates signature algorithm oid to erlang digest and signature types.
+ </p>
+ </desc>
+ </func>
+
<func>
<name>pkix_verify(Cert, Key) -> boolean()</name>
<fsummary> Verify pkix x.509 certificate signature.</fsummary>
@@ -511,8 +559,8 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<d>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.</d>
- <v>DigestType = rsa_digest_type() | dss_digest_type()</v>
- <v>Key = rsa_private_key() | dsa_private_key()</v>
+ <v>DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()</v>
+ <v>Key = rsa_private_key() | dsa_private_key() | ec_private_key()</v>
</type>
<desc>
<p> Creates a digital signature.</p>
@@ -575,12 +623,12 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<v>Msg = binary() | {digest,binary()}</v>
<d>The msg is either the binary "plain text" data
or it is the hashed value of "plain text" i.e. the digest.</d>
- <v>DigestType = rsa_digest_type() | dss_digest_type()</v>
+ <v>DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()</v>
<v>Signature = binary()</v>
- <v>Key = rsa_public_key() | dsa_public_key()</v>
- </type>
- <desc>
- <p>Verifies a digital signature</p>
+ <v>Key = rsa_public_key() | dsa_public_key() | ec_public_key()</v>
+ </type>
+ <desc>
+ <p>Verifies a digital signature</p>
</desc>
</func>
diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl
index 4d1d510f29..1e882e76ee 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
@@ -72,6 +72,10 @@
valid_ext
}).
+-record('ECPoint', {
+ point
+ }).
+
-define(unspecified, 0).
-define(keyCompromise, 1).
@@ -89,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()} | #'ECParameters'{}}.
+-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/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl
index f53c94b334..dc8d68c78f 100644
--- a/lib/public_key/src/pubkey_cert.erl
+++ b/lib/public_key/src/pubkey_cert.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2011. 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
@@ -27,7 +27,7 @@
validate_time/3, validate_signature/6,
validate_issuer/4, validate_names/6,
validate_extensions/4,
- normalize_general_name/1, digest_type/1, is_self_signed/1,
+ normalize_general_name/1, is_self_signed/1,
is_issuer/2, issuer_id/2, is_fixed_dh_cert/1,
verify_data/1, verify_fun/4, select_extension/2, match_name/3,
extensions_list/1, cert_auth_key_id/1, time_str_2_gregorian_sec/1]).
@@ -426,13 +426,12 @@ extensions_list(asn1_NOVALUE) ->
extensions_list(Extensions) ->
Extensions.
-
extract_verify_data(OtpCert, DerCert) ->
{_, Signature} = OtpCert#'OTPCertificate'.signature,
SigAlgRec = OtpCert#'OTPCertificate'.signatureAlgorithm,
SigAlg = SigAlgRec#'SignatureAlgorithm'.algorithm,
PlainText = encoded_tbs_cert(DerCert),
- DigestType = digest_type(SigAlg),
+ {DigestType,_} = public_key:pkix_sign_types(SigAlg),
{DigestType, PlainText, Signature}.
verify_signature(OtpCert, DerCert, Key, KeyParams) ->
@@ -451,21 +450,6 @@ encoded_tbs_cert(Cert) ->
{'Certificate_tbsCertificate', EncodedTBSCert}, _, _} = PKIXCert,
EncodedTBSCert.
-digest_type(?sha1WithRSAEncryption) ->
- sha;
-digest_type(?sha224WithRSAEncryption) ->
- sha224;
-digest_type(?sha256WithRSAEncryption) ->
- sha256;
-digest_type(?sha384WithRSAEncryption) ->
- sha384;
-digest_type(?sha512WithRSAEncryption) ->
- sha512;
-digest_type(?md5WithRSAEncryption) ->
- md5;
-digest_type(?'id-dsa-with-sha1') ->
- sha.
-
public_key_info(PublicKeyInfo,
#path_validation_state{working_public_key_algorithm =
WorkingAlgorithm,
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_crl.erl b/lib/public_key/src/pubkey_crl.erl
index 3e4c3c8b6d..eaba5bfa1b 100644
--- a/lib/public_key/src/pubkey_crl.erl
+++ b/lib/public_key/src/pubkey_crl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
@@ -561,7 +561,7 @@ extract_crl_verify_data(CRL, DerCRL) ->
#'AlgorithmIdentifier'{algorithm = SigAlg} =
CRL#'CertificateList'.signatureAlgorithm,
PlainText = encoded_tbs_crl(DerCRL),
- DigestType = pubkey_cert:digest_type(SigAlg),
+ {DigestType, _} = public_key:pkix_sign_types(SigAlg),
{DigestType, PlainText, Signature}.
encoded_tbs_crl(CRL) ->
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 e753cf3867..648dba3d5a 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -35,7 +35,10 @@
encrypt_public/2, encrypt_public/3,
decrypt_public/2, decrypt_public/3,
sign/3, verify/4,
+ generate_key/1,
+ compute_key/2, compute_key/3,
pkix_sign/2, pkix_verify/2,
+ pkix_sign_types/1,
pkix_is_self_signed/1,
pkix_is_fixed_dh_cert/1,
pkix_is_issuer/2,
@@ -51,8 +54,10 @@
-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().
-define(UINT32(X), X:32/unsigned-big-integer).
-define(DER_NULL, <<5, 0>>).
@@ -92,7 +97,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};
+ 'ECPoint' ->
+ der_decode(KeyType, Key0)
end;
pem_entry_decode({Asn1Type, Der, not_encrypted}) when is_atom(Asn1Type),
is_binary(Der) ->
@@ -249,10 +256,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, 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()) ->
@@ -316,84 +322,115 @@ 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, format_rsa_private_key(Key), Padding).
-
-
-format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E,
- privateExponent = D,
- prime1 = P1, prime2 = P2,
- exponent1 = E1, exponent2 = E2,
- coefficient = C})
- when is_integer(P1), is_integer(P2),
- is_integer(E1), is_integer(E2), is_integer(C) ->
- [crypto:mpint(K) || K <- [E, N, D, P1, P2, E1, E2, C]];
-
-format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E,
- privateExponent = D}) ->
- [crypto:mpint(K) || K <- [E, N, D]].
-
-%%--------------------------------------------------------------------
--spec sign(binary() | {digest, binary()}, rsa_digest_type() | dss_digest_type(),
+ crypto:private_encrypt(rsa, PlainText, format_rsa_private_key(Key), Padding).
+
+%%--------------------------------------------------------------------
+-spec generate_key(#'DHParameter'{} | {namedCurve, Name ::atom()} |
+ #'ECParameters'{}) -> {Public::binary(), Private::binary()} |
+ #'ECPrivateKey'{}.
+%% Description: Generates a new keypair
+%%--------------------------------------------------------------------
+generate_key(#'DHParameter'{prime = P, base = G}) ->
+ crypto:generate_key(dh, [P, G]);
+generate_key({namedCurve, _} = Params) ->
+ ec_generate_key(Params);
+generate_key(#'ECParameters'{} = Params) ->
+ ec_generate_key(Params).
+
+%%--------------------------------------------------------------------
+-spec compute_key(#'ECPoint'{} , #'ECPrivateKey'{}) -> binary().
+-spec compute_key(OthersKey ::binary(), MyKey::binary(), #'DHParameter'{}) -> binary().
+%% Description: Compute shared secret
+%%--------------------------------------------------------------------
+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:compute_key(dh, PubKey, PrivKey, [P, G]).
+
+%%--------------------------------------------------------------------
+-spec pkix_sign_types(SignatureAlg::oid()) ->
+ %% Relevant dsa digest type is subpart of rsa digest type
+ { DigestType :: rsa_digest_type(),
+ SignatureType :: rsa | dsa | ecdsa
+ }.
+%% Description:
+%%--------------------------------------------------------------------
+pkix_sign_types(?sha1WithRSAEncryption) ->
+ {sha, rsa};
+pkix_sign_types(?'sha-1WithRSAEncryption') ->
+ {sha, rsa};
+pkix_sign_types(?sha224WithRSAEncryption) ->
+ {sha224, rsa};
+pkix_sign_types(?sha256WithRSAEncryption) ->
+ {sha256, rsa};
+pkix_sign_types(?sha384WithRSAEncryption) ->
+ {sha384, rsa};
+pkix_sign_types(?sha512WithRSAEncryption) ->
+ {sha512, rsa};
+pkix_sign_types(?md5WithRSAEncryption) ->
+ {md5, rsa};
+pkix_sign_types(?'id-dsa-with-sha1') ->
+ {sha, dsa};
+pkix_sign_types(?'id-dsaWithSHA1') ->
+ {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() | ecdsa_digest_type(),
rsa_private_key() |
- dsa_private_key()) -> Signature :: binary().
+ dsa_private_key() | ec_private_key()) -> Signature :: binary().
%% Description: Create digital signature.
%%--------------------------------------------------------------------
-sign({digest,_}=Digest, DigestType, Key = #'RSAPrivateKey'{}) ->
- crypto:rsa_sign(DigestType, Digest, format_rsa_private_key(Key));
-
-sign(PlainText, DigestType, Key = #'RSAPrivateKey'{}) ->
- crypto:rsa_sign(DigestType, sized_binary(PlainText), format_rsa_private_key(Key));
+sign(DigestOrPlainText, DigestType, Key = #'RSAPrivateKey'{}) ->
+ crypto:sign(rsa, DigestType, DigestOrPlainText, format_rsa_private_key(Key));
-sign({digest,_}=Digest, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) ->
- crypto:dss_sign(Digest,
- [crypto:mpint(P), crypto:mpint(Q),
- crypto:mpint(G), crypto:mpint(X)]);
+sign(DigestOrPlainText, sha, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) ->
+ crypto:sign(dss, sha, DigestOrPlainText, [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)]);
+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) ->
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({digest,_}=Digest, DigestType, Signature,
+verify(DigestOrPlainText, 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, DigestOrPlainText, 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)]);
+verify(DigestOrPlaintext, DigestType, Signature, {#'ECPoint'{point = Point}, Param}) ->
+ ECCurve = ec_curve_spec(Param),
+ crypto:verify(ecdsa, DigestType, DigestOrPlaintext, Signature, [Point, ECCurve]);
-verify({digest,_}=Digest, sha, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}})
- when is_integer(Key), is_binary(Signature) ->
- crypto:dss_verify(Digest, sized_binary(Signature),
- [crypto:mpint(P), crypto:mpint(Q),
- crypto:mpint(G), crypto:mpint(Key)]);
%% Backwards compatibility
verify(Digest, none, Signature, {_, #'Dss-Parms'{}} = Key ) ->
verify({digest,Digest}, sha, Signature, Key);
-verify(PlainText, sha, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}})
- when is_integer(Key), is_binary(PlainText), is_binary(Signature) ->
- crypto:dss_verify(sized_binary(PlainText),
- sized_binary(Signature),
- [crypto:mpint(P), crypto:mpint(Q),
- crypto:mpint(G), crypto:mpint(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'{},
rsa_private_key() | dsa_private_key()) -> Der::binary().
@@ -406,7 +443,7 @@ pkix_sign(#'OTPTBSCertificate'{signature =
= SigAlg} = TBSCert, Key) ->
Msg = pkix_encode('OTPTBSCertificate', TBSCert, otp),
- DigestType = pubkey_cert:digest_type(Alg),
+ {DigestType, _} = pkix_sign_types(Alg),
Signature = sign(Msg, DigestType, Key),
Cert = #'OTPCertificate'{tbsCertificate= TBSCert,
signatureAlgorithm = SigAlg,
@@ -416,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.
%%--------------------------------------------------------------------
@@ -428,7 +465,12 @@ 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, Key = {#'ECPoint'{}, _})
+ 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'{},
@@ -610,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, [crypto:mpint(E),crypto:mpint(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,[crypto:mpint(E), crypto:mpint(N)],
- Padding).
+ crypto:public_decrypt(rsa, CipherText,[E, N], Padding).
path_validation([], #path_validation_state{working_public_key_algorithm
= Algorithm,
@@ -702,10 +742,6 @@ validate(Cert, #path_validation_state{working_issuer_name = Issuer,
pubkey_cert:prepare_for_next_cert(OtpCert, ValidationState).
-sized_binary(Binary) ->
- Size = size(Binary),
- <<?UINT32(Size), Binary/binary>>.
-
otp_cert(Der) when is_binary(Der) ->
pkix_decode_cert(Der, otp);
otp_cert(#'OTPCertificate'{} =Cert) ->
@@ -812,3 +848,46 @@ 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].
+
+ec_generate_key(Params) ->
+ Curve = ec_curve_spec(Params),
+ Term = crypto:generate_key(ecdh, Curve),
+ ec_key(Term, Params).
+
+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}) ->
+ pubkey_cert_records:namedCurves(OID).
+
+ec_key({PrivateKey, PubKey}, Params) ->
+ #'ECPrivateKey'{version = 1,
+ privateKey = int2list(PrivateKey),
+ parameters = Params,
+ publicKey = {0, PubKey}}.
+
+list2int(L) ->
+ S = length(L) * 8,
+ <<R:S/integer>> = erlang:iolist_to_binary(L),
+ R.
+int2list(I) ->
+ L = (length(integer_to_list(I, 16)) + 1) div 2,
+ binary_to_list(<<I:(L*8)>>).
diff --git a/lib/public_key/test/erl_make_certs.erl b/lib/public_key/test/erl_make_certs.erl
index 95e288cd71..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)
@@ -91,6 +91,16 @@ gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(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()
%% @end
@@ -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)
@@ -354,13 +391,13 @@ gen_dsa2(LSize, NSize) ->
X0 = prime(LSize),
P0 = prime((LSize div 2) +1),
- %% Choose L-bit prime modulus P such that p–1 is a multiple of q.
+ %% Choose L-bit prime modulus P such that p-1 is a multiple of q.
case dsa_search(X0 div (2*Q*P0), P0, Q, 1000) of
error ->
gen_dsa2(LSize, NSize);
P ->
G = crypto:mod_exp(2, (P-1) div Q, P), % Choose G a number whose multiplicative order modulo p is q.
- %% such that This may be done by setting g = h^(p–1)/q mod p, commonly h=2 is used.
+ %% such that This may be done by setting g = h^(p-1)/q mod p, commonly h=2 is used.
X = prime(20), %% Choose x by some random method, where 0 < x < q.
Y = crypto:mod_exp(G, X, P), %% Calculate y = g^x mod p.
@@ -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(<<I:(L*8)>>).
+
+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,
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 ea48479f0b..5a64140c67 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_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
@@ -41,7 +41,8 @@ all() ->
{group, ssh_public_key_decode_encode},
encrypt_decrypt,
{group, sign_verify},
- pkix, pkix_countryname, pkix_path_validation].
+ pkix, pkix_countryname, pkix_path_validation,
+ pkix_iso_rsa_oid, pkix_iso_dsa_oid].
groups() ->
[{pem_decode_encode, [], [dsa_pem, rsa_pem, encrypted_pem,
@@ -550,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,
@@ -688,6 +689,31 @@ pkix_path_validation(Config) when is_list(Config) ->
public_key:pkix_path_validation(unknown_ca, [Cert1], [{verify_fun,
VerifyFunAndState1}]),
ok.
+
+%%--------------------------------------------------------------------
+pkix_iso_rsa_oid() ->
+ [{doc, "Test workaround for supporting certs that use ISO oids"
+ " 1.3.14.3.2.29 instead of PKIX/PKCS oid"}].
+pkix_iso_rsa_oid(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+ {ok, PemCert} = file:read_file(filename:join(Datadir, "rsa_ISO.pem")),
+ [{_, Cert, _}] = public_key:pem_decode(PemCert),
+ OTPCert = public_key:pkix_decode_cert(Cert, otp),
+ SigAlg = OTPCert#'OTPCertificate'.signatureAlgorithm,
+ {_, rsa} = public_key:pkix_sign_types(SigAlg#'SignatureAlgorithm'.algorithm).
+
+%%--------------------------------------------------------------------
+pkix_iso_dsa_oid() ->
+ [{doc, "Test workaround for supporting certs that use ISO oids"
+ "1.3.14.3.2.27 instead of PKIX/PKCS oid"}].
+pkix_iso_dsa_oid(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+ {ok, PemCert} = file:read_file(filename:join(Datadir, "dsa_ISO.pem")),
+ [{_, Cert, _}] = public_key:pem_decode(PemCert),
+ OTPCert = public_key:pkix_decode_cert(Cert, otp),
+ SigAlg = OTPCert#'OTPCertificate'.signatureAlgorithm,
+ {_, dsa} = public_key:pkix_sign_types(SigAlg#'SignatureAlgorithm'.algorithm).
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
diff --git a/lib/public_key/test/public_key_SUITE_data/dsa_ISO.pem b/lib/public_key/test/public_key_SUITE_data/dsa_ISO.pem
new file mode 100644
index 0000000000..d3541367f0
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/dsa_ISO.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEEjCCAqygAwIBAgIQZIIqq4RXfpBKJXV69Jc4BjCCASwGByqGSM44BAMwggEf
+AoGBALez5tklY5CdFeTMos899pA6i4u4uCtszgBzrdBk6cl5FVqzdzWMGTQiynnT
+pGsrOESinzP06Ip+pG15We2OORwgvCxD/W95aCiN0/+MdiXqlsmboBARMzsa+SmB
+ENN3gF/+tuuEAFzOXU1q2cmEywRLyfbM2KIBVE/TChWYw2eRAhUA1R64VvcQ90XA
+8SOKVDmMA0dBzukCgYEAlLMYP0pbgBlgHQVO3/avAHlWNrIq52Lxk7SdPJWgMvPj
+TK9Z6sv88kxsCcydtjvO439j1yqcwk50GQc+86ktBWWz93/HkIdnFyqafef4mmWv
+m2Uq6ClQKS+A0Asfaj8Mys+HUMiI+qsfdjRbyIpwb7MX1nsVdsKzALnZNMW27A0w
+HTEbMBkGA1UEAxMSSVNBIFRlc3QgQXV0aG9yaXR5MB4XDTEyMDMyMDE3MTMyMVoX
+DTM5MTIzMTIzNTk1OVowHTEbMBkGA1UEAxMSSVNBIFRlc3QgQXV0aG9yaXR5MIGf
+MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqe3oVLIVBVIPI/uZjrciELODKxPEE
+SDWoNvycEeP1ERF5kDlRDmLIQ51Nt0vI5pKTasnIDbB1ONiQ2cvMrj2dkWWl/z2v
+f9tqQAzBm/r1LcUmL1bbP2bgk+//n5AJicU1FKecfDeZo0SXChDKSfH3ojdbsS5U
+68q0qGHgNoPRawIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ME4GA1UdAQRHMEWA
+EEIfCfbwCZs35y8mXWInVuyhHzAdMRswGQYDVQQDExJJU0EgVGVzdCBBdXRob3Jp
+dHmCEGSCKquEV36QSiV1evSXOAYwggEsBgcqhkjOOAQDMIIBHwKBgQC3s+bZJWOQ
+nRXkzKLPPfaQOouLuLgrbM4Ac63QZOnJeRVas3c1jBk0Isp506RrKzhEop8z9OiK
+fqRteVntjjkcILwsQ/1veWgojdP/jHYl6pbJm6AQETM7GvkpgRDTd4Bf/rbrhABc
+zl1NatnJhMsES8n2zNiiAVRP0woVmMNnkQIVANUeuFb3EPdFwPEjilQ5jANHQc7p
+AoGBAJSzGD9KW4AZYB0FTt/2rwB5VjayKudi8ZO0nTyVoDLz40yvWerL/PJMbAnM
+nbY7zuN/Y9cqnMJOdBkHPvOpLQVls/d/x5CHZxcqmn3n+Jplr5tlKugpUCkvgNAL
+H2o/DMrPh1DIiPqrH3Y0W8iKcG+zF9Z7FXbCswC52TTFtuwNAzAAMC0CFH/KmkwI
+wnL9ecefLjQZ9Au52Kt5AhUAqJ5UEy2hIjCkdBoyuwOVPp5qnUw=
+-----END CERTIFICATE-----
diff --git a/lib/public_key/test/public_key_SUITE_data/rsa_ISO.pem b/lib/public_key/test/public_key_SUITE_data/rsa_ISO.pem
new file mode 100644
index 0000000000..f82efdefc5
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/rsa_ISO.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICGjCCAYegAwIBAgIQZIIqq4RXfpBKJXV69Jc4BjAJBgUrDgMCHQUAMB0xGzAZ
+BgNVBAMTEklTQSBUZXN0IEF1dGhvcml0eTAeFw0xMjAzMjAxNzEzMjFaFw0zOTEy
+MzEyMzU5NTlaMB0xGzAZBgNVBAMTEklTQSBUZXN0IEF1dGhvcml0eTCBnzANBgkq
+hkiG9w0BAQEFAAOBjQAwgYkCgYEAqnt6FSyFQVSDyP7mY63IhCzgysTxBEg1qDb8
+nBHj9REReZA5UQ5iyEOdTbdLyOaSk2rJyA2wdTjYkNnLzK49nZFlpf89r3/bakAM
+wZv69S3FJi9W2z9m4JPv/5+QCYnFNRSnnHw3maNElwoQyknx96I3W7EuVOvKtKhh
+4DaD0WsCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zBOBgNVHQEERzBFgBBCHwn2
+8AmbN+cvJl1iJ1bsoR8wHTEbMBkGA1UEAxMSSVNBIFRlc3QgQXV0aG9yaXR5ghBk
+giqrhFd+kEoldXr0lzgGMAkGBSsOAwIdBQADgYEAIlVecua5Cr1z/cdwQ8znlgOU
+U+y/uzg0nupKkopzVnRYhwV4hxZt3izAz4C/SJZB7eL0bUKlg1ceGjbQsGEm0fzF
+LEV3vym4G51bxv03Iecwo96G4NgjJ7+9/7ciBVzfxZyfuCpYG1M2LyrbOyuevtTy
+2+vIueT0lv6UftgBfIE=
+-----END CERTIFICATE-----