Browse Source

Implement draft-ietf-curdle-pkix-04's serialization.

The resulting EVP_PKEYs do not do anything useful yet, but we are able
to parse them. Teaching them to sign will be done in a follow-up.

Creating these from in-memory keys is also slightly different from other
types. We don't have or need a public ED25519_KEY struct in
curve25519.h, so I've added tighter constructor functions which should
hopefully be easier to use anyway.

BUG=187

Change-Id: I0bbeea37350d4fdca05b6c6c0f152c15e6ade5bb
Reviewed-on: https://boringssl-review.googlesource.com/14446
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin 7 years ago
committed by Adam Langley
parent
commit
05bb1c5033
14 changed files with 359 additions and 5 deletions
  1. +1
    -0
      crypto/err/evp.errordata
  2. +1
    -0
      crypto/evp/CMakeLists.txt
  3. +2
    -0
      crypto/evp/evp.c
  4. +2
    -2
      crypto/evp/evp_asn1.c
  5. +82
    -0
      crypto/evp/evp_extra_test.cc
  6. +3
    -0
      crypto/evp/evp_test.cc
  7. +30
    -0
      crypto/evp/evp_tests.txt
  8. +1
    -0
      crypto/evp/internal.h
  9. +207
    -0
      crypto/evp/p_ed25519_asn1.c
  10. +8
    -2
      crypto/obj/obj_dat.h
  11. +1
    -0
      crypto/obj/obj_mac.num
  12. +3
    -0
      crypto/obj/objects.txt
  13. +13
    -1
      include/openssl/evp.h
  14. +5
    -0
      include/openssl/nid.h

+ 1
- 0
crypto/err/evp.errordata View File

@@ -17,6 +17,7 @@ EVP,115,INVALID_PADDING_MODE
EVP,116,INVALID_PSS_SALTLEN
EVP,117,KEYS_NOT_SET
EVP,118,MISSING_PARAMETERS
EVP,130,NOT_A_PRIVATE_KEY
EVP,119,NO_DEFAULT_DIGEST
EVP,120,NO_KEY_SET
EVP,121,NO_MDC2_SUPPORT


+ 1
- 0
crypto/evp/CMakeLists.txt View File

@@ -12,6 +12,7 @@ add_library(
p_dsa_asn1.c
p_ec.c
p_ec_asn1.c
p_ed25519_asn1.c
p_rsa.c
p_rsa_asn1.c
pbkdf.c


+ 2
- 0
crypto/evp/evp.c View File

@@ -198,6 +198,8 @@ static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) {
return &ec_asn1_meth;
case EVP_PKEY_DSA:
return &dsa_asn1_meth;
case EVP_PKEY_ED25519:
return &ed25519_asn1_meth;
default:
return NULL;
}


+ 2
- 2
crypto/evp/evp_asn1.c View File

@@ -72,6 +72,7 @@ static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = {
&rsa_asn1_meth,
&ec_asn1_meth,
&dsa_asn1_meth,
&ed25519_asn1_meth,
};

static int parse_key_type(CBS *cbs, int *out_type) {
@@ -80,8 +81,7 @@ static int parse_key_type(CBS *cbs, int *out_type) {
return 0;
}

unsigned i;
for (i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) {
for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) {
const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i];
if (CBS_len(&oid) == method->oid_len &&
OPENSSL_memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) {


+ 82
- 0
crypto/evp/evp_extra_test.cc View File

@@ -540,3 +540,85 @@ TEST(EVPExtraTest, d2i_PrivateKey) {
sizeof(kExampleRSAKeyPKCS8)));
ERR_clear_error();
}

TEST(EVPExtraTest, Ed25519) {
static const uint8_t kPublicKey[32] = {
0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe,
0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6,
0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a,
};

static const uint8_t kPublicKeySPKI[] = {
0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21,
0x00, 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b,
0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda,
0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a,
};

static const uint8_t kPrivateKey[64] = {
0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84, 0x4a,
0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32,
0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60, 0xd7,
0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, 0xd3,
0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23,
0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a,
};

static const uint8_t kPrivateKeyPKCS8[] = {
0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70,
0x04, 0x22, 0x04, 0x20, 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60,
0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69,
0x7b, 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60,
};

// Create a public key.
bssl::UniquePtr<EVP_PKEY> pubkey(EVP_PKEY_new_ed25519_public(kPublicKey));
ASSERT_TRUE(pubkey);
EXPECT_EQ(EVP_PKEY_ED25519, EVP_PKEY_id(pubkey.get()));

// The public key must encode properly.
bssl::ScopedCBB cbb;
uint8_t *der;
size_t der_len;
ASSERT_TRUE(CBB_init(cbb.get(), 0));
ASSERT_TRUE(EVP_marshal_public_key(cbb.get(), pubkey.get()));
ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len));
bssl::UniquePtr<uint8_t> free_der(der);
EXPECT_EQ(Bytes(kPublicKeySPKI), Bytes(der, der_len));

// The public key must gracefully fail to encode as a private key.
ASSERT_TRUE(CBB_init(cbb.get(), 0));
EXPECT_FALSE(EVP_marshal_private_key(cbb.get(), pubkey.get()));
uint32_t err = ERR_get_error();
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
EXPECT_EQ(EVP_R_NOT_A_PRIVATE_KEY, ERR_GET_REASON(err));
cbb.Reset();

// Create a private key.
bssl::UniquePtr<EVP_PKEY> privkey(EVP_PKEY_new_ed25519_private(kPrivateKey));
ASSERT_TRUE(privkey);
EXPECT_EQ(EVP_PKEY_ED25519, EVP_PKEY_id(privkey.get()));

// The public key must encode from the private key.
ASSERT_TRUE(CBB_init(cbb.get(), 0));
ASSERT_TRUE(EVP_marshal_public_key(cbb.get(), privkey.get()));
ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len));
free_der.reset(der);
EXPECT_EQ(Bytes(kPublicKeySPKI), Bytes(der, der_len));

// The private key must encode properly.
ASSERT_TRUE(CBB_init(cbb.get(), 0));
ASSERT_TRUE(EVP_marshal_private_key(cbb.get(), privkey.get()));
ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len));
free_der.reset(der);
EXPECT_EQ(Bytes(kPrivateKeyPKCS8), Bytes(der, der_len));

// Test EVP_PKEY_cmp.
EXPECT_TRUE(EVP_PKEY_cmp(pubkey.get(), privkey.get()));

static const uint8_t kZeros[32] = {0};
bssl::UniquePtr<EVP_PKEY> pubkey2(EVP_PKEY_new_ed25519_public(kZeros));
ASSERT_TRUE(pubkey2);
EXPECT_FALSE(EVP_PKEY_cmp(pubkey.get(), pubkey2.get()));
EXPECT_FALSE(EVP_PKEY_cmp(privkey.get(), pubkey2.get()));
}

+ 3
- 0
crypto/evp/evp_test.cc View File

@@ -110,6 +110,9 @@ static int GetKeyType(FileTest *t, const std::string &name) {
if (name == "DSA") {
return EVP_PKEY_DSA;
}
if (name == "Ed25519") {
return EVP_PKEY_ED25519;
}
t->PrintLine("Unknown key type: '%s'", name.c_str());
return EVP_PKEY_NONE;
}


+ 30
- 0
crypto/evp/evp_tests.txt View File

@@ -84,6 +84,36 @@ PublicKey = DSA-1024-SPKI-No-Params
Type = DSA
Input = 308192300906072a8648ce38040103818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a

# An Ed25519 private key.
PrivateKey = Ed25519
Type = Ed25519
Input = 302e020100300506032b6570042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60

# The same as the above, but with an invalid NULL parameter.
PrivateKey = Ed25519-NULL
Input = 3030020100300706032b65700500042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
Error = DECODE_ERROR

# The above key as an SPKI.
PublicKey = Ed25519-SPKI
Type = Ed25519
Input = 302a300506032b6570032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a

# The same as the above, but with an invalid NULL parameter.
PublicKey = Ed25519-SPKI-NULL
Input = 302c300706032b65700500032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
Error = DECODE_ERROR

# Sample public key from draft-ietf-curdle-pkix-04.
PublicKey = Ed25519-SPKI-Spec
Type = Ed25519
Input = 302a300506032b657003210019bf44096984cdfe8541bac167dc3b96c85086aa30b6b6cb0c5c38ad703166e1

# Sample private key from draft-ietf-curdle-pkix-04.
PrivateKey = Ed25519-Spec
Type = Ed25519
Input = 302e020100300506032b657004220420d4ee72dbf913584ad5b6d8f1f769f8ad3afe7c28cbf1d4fbe097a88f44755842


# RSA tests



+ 1
- 0
crypto/evp/internal.h View File

@@ -219,6 +219,7 @@ struct evp_pkey_method_st {
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth;

extern const EVP_PKEY_METHOD rsa_pkey_meth;
extern const EVP_PKEY_METHOD ec_pkey_meth;


+ 207
- 0
crypto/evp/p_ed25519_asn1.c View File

@@ -0,0 +1,207 @@
/* Copyright (c) 2017, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <openssl/evp.h>

#include <openssl/bytestring.h>
#include <openssl/curve25519.h>
#include <openssl/err.h>
#include <openssl/mem.h>

#include "internal.h"
#include "../internal.h"


typedef struct {
union {
uint8_t priv[64];
struct {
/* Shift the location of the public key to align with where it is in the
* private key representation. */
uint8_t pad[32];
uint8_t value[32];
} pub;
} key;
char has_private;
} ED25519_KEY;

static void ed25519_free(EVP_PKEY *pkey) {
if (pkey->pkey.ptr != NULL) {
ED25519_KEY *key = pkey->pkey.ptr;
OPENSSL_cleanse(key, sizeof(ED25519_KEY));
OPENSSL_free(key);
pkey->pkey.ptr = NULL;
}
}

static int set_pubkey(EVP_PKEY *pkey, const uint8_t pubkey[32]) {
ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY));
if (key == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
key->has_private = 0;
OPENSSL_memcpy(key->key.pub.value, pubkey, 32);

ed25519_free(pkey);
pkey->pkey.ptr = key;
return 1;
}

static int set_privkey(EVP_PKEY *pkey, const uint8_t privkey[64]) {
ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY));
if (key == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
key->has_private = 1;
OPENSSL_memcpy(key->key.priv, privkey, 64);

ed25519_free(pkey);
pkey->pkey.ptr = key;
return 1;
}

static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
/* See draft-ietf-curdle-pkix-04, section 4. */

/* The parameters must be omitted. Public keys have length 32. */
if (CBS_len(params) != 0 ||
CBS_len(key) != 32) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}

return set_pubkey(out, CBS_data(key));
}

static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) {
const ED25519_KEY *key = pkey->pkey.ptr;

/* See draft-ietf-curdle-pkix-04, section 4. */
CBB spki, algorithm, oid, key_bitstring;
if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
!CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) ||
!CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
!CBB_add_u8(&key_bitstring, 0 /* padding */) ||
!CBB_add_bytes(&key_bitstring, key->key.pub.value, 32) ||
!CBB_flush(out)) {
OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
return 0;
}

return 1;
}

static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
const ED25519_KEY *a_key = a->pkey.ptr;
const ED25519_KEY *b_key = b->pkey.ptr;
return OPENSSL_memcmp(a_key->key.pub.value, b_key->key.pub.value, 32) == 0;
}

static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
/* See draft-ietf-curdle-pkix-04, section 7. */

/* Parameters must be empty. The key is a 32-byte value wrapped in an extra
* OCTET STRING layer. */
CBS inner;
if (CBS_len(params) != 0 ||
!CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) ||
CBS_len(key) != 0 ||
CBS_len(&inner) != 32) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}

/* The PKCS#8 encoding stores only the 32-byte seed, so we must recover the
* full representation which we use from it. */
uint8_t pubkey[32], privkey[64];
ED25519_keypair_from_seed(pubkey, privkey, CBS_data(&inner));
return set_privkey(out, privkey);
}

static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) {
ED25519_KEY *key = pkey->pkey.ptr;
if (!key->has_private) {
OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY);
return 0;
}

/* See draft-ietf-curdle-pkix-04, section 7. */
CBB pkcs8, algorithm, oid, private_key, inner;
if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
!CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
!CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) ||
!CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
!CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) ||
/* The PKCS#8 encoding stores only the 32-byte seed which is the first 32
* bytes of the private key. */
!CBB_add_bytes(&inner, key->key.priv, 32) ||
!CBB_flush(out)) {
OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
return 0;
}

return 1;
}

static int ed25519_size(const EVP_PKEY *pkey) { return 64; }

static int ed25519_bits(const EVP_PKEY *pkey) { return 256; }

const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
EVP_PKEY_ED25519,
{0x2b, 0x65, 0x70},
3,
ed25519_pub_decode,
ed25519_pub_encode,
ed25519_pub_cmp,
ed25519_priv_decode,
ed25519_priv_encode,
NULL /* pkey_opaque */,
ed25519_size,
ed25519_bits,
NULL /* param_missing */,
NULL /* param_copy */,
NULL /* param_cmp */,
ed25519_free,
};

EVP_PKEY *EVP_PKEY_new_ed25519_public(const uint8_t public_key[32]) {
EVP_PKEY *ret = EVP_PKEY_new();
if (ret == NULL ||
!EVP_PKEY_set_type(ret, EVP_PKEY_ED25519) ||
!set_pubkey(ret, public_key)) {
EVP_PKEY_free(ret);
return NULL;
}

return ret;
}

EVP_PKEY *EVP_PKEY_new_ed25519_private(const uint8_t private_key[64]) {
EVP_PKEY *ret = EVP_PKEY_new();
if (ret == NULL ||
!EVP_PKEY_set_type(ret, EVP_PKEY_ED25519) ||
!set_privkey(ret, private_key)) {
EVP_PKEY_free(ret);
return NULL;
}

return ret;
}

+ 8
- 2
crypto/obj/obj_dat.h View File

@@ -56,7 +56,7 @@

/* This file is generated by crypto/obj/objects.go. */

#define NUM_NID 949
#define NUM_NID 950

static const uint8_t kObjectData[] = {
/* NID_rsadsi */
@@ -1811,6 +1811,8 @@ static const uint8_t kObjectData[] = {
0x2b, 0x81, 0x04, 0x01, 0x0e, 0x02,
/* NID_dhSinglePass_cofactorDH_sha512kdf_scheme */
0x2b, 0x81, 0x04, 0x01, 0x0e, 0x03,
/* NID_Ed25519 */
0x2b, 0x65, 0x70,
};

static const ASN1_OBJECT kObjects[NUM_NID] = {
@@ -3440,6 +3442,7 @@ static const ASN1_OBJECT kObjects[NUM_NID] = {
{"dh-std-kdf", "dh-std-kdf", NID_dh_std_kdf, 0, NULL, 0},
{"dh-cofactor-kdf", "dh-cofactor-kdf", NID_dh_cofactor_kdf, 0, NULL, 0},
{"X25519", "X25519", NID_X25519, 0, NULL, 0},
{"Ed25519", "Ed25519", NID_Ed25519, 3, &kObjectData[6175], 0},
};

static const unsigned kNIDsInShortNameOrder[] = {
@@ -3528,6 +3531,7 @@ static const unsigned kNIDsInShortNameOrder[] = {
70 /* DSA-SHA1-old */,
67 /* DSA-old */,
297 /* DVCS */,
949 /* Ed25519 */,
99 /* GN */,
855 /* HMAC */,
780 /* HMAC-MD5 */,
@@ -4400,6 +4404,7 @@ static const unsigned kNIDsInLongNameOrder[] = {
382 /* Directory */,
392 /* Domain */,
132 /* E-mail Protection */,
949 /* Ed25519 */,
389 /* Enterprises */,
384 /* Experimental */,
372 /* Extended OCSP Status */,
@@ -5334,7 +5339,8 @@ static const unsigned kNIDsInOIDOrder[] = {
378 /* 2.5.8 (OBJ_X500algorithms) */, 81 /* 2.5.29 (OBJ_id_ce) */,
512 /* 2.23.42 (OBJ_id_set) */, 678 /* 2.23.43 (OBJ_wap) */,
435 /* 0.9.2342 (OBJ_pss) */, 183 /* 1.2.840 (OBJ_ISO_US) */,
381 /* 1.3.6.1 (OBJ_iana) */, 677 /* 1.3.132 (OBJ_certicom_arc) */,
381 /* 1.3.6.1 (OBJ_iana) */, 949 /* 1.3.101.112 (OBJ_Ed25519) */,
677 /* 1.3.132 (OBJ_certicom_arc) */,
394 /* 2.5.1.5 (OBJ_selected_attribute_types) */,
13 /* 2.5.4.3 (OBJ_commonName) */, 100 /* 2.5.4.4 (OBJ_surname) */,
105 /* 2.5.4.5 (OBJ_serialNumber) */, 14 /* 2.5.4.6 (OBJ_countryName) */,


+ 1
- 0
crypto/obj/obj_mac.num View File

@@ -937,3 +937,4 @@ dhSinglePass_cofactorDH_sha512kdf_scheme 945
dh_std_kdf 946
dh_cofactor_kdf 947
X25519 948
Ed25519 949

+ 3
- 0
crypto/obj/objects.txt View File

@@ -1333,3 +1333,6 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme

# NID for X25519 (no corresponding OID).
: X25519

# See draft-ietf-curdle-pkix-04.
1 3 101 112 : Ed25519

+ 13
- 1
include/openssl/evp.h View File

@@ -157,10 +157,21 @@ OPENSSL_EXPORT int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key);
OPENSSL_EXPORT EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey);
OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);

/* EVP_PKEY_new_ed25519_public returns a newly allocated |EVP_PKEY| wrapping an
* Ed25519 public key, or NULL on allocation error. */
OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_ed25519_public(
const uint8_t public_key[32]);

/* EVP_PKEY_new_ed25519_private returns a newly allocated |EVP_PKEY| wrapping an
* Ed25519 private key, or NULL on allocation error. */
OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_ed25519_private(
const uint8_t private_key[64]);

#define EVP_PKEY_NONE NID_undef
#define EVP_PKEY_RSA NID_rsaEncryption
#define EVP_PKEY_DSA NID_dsa
#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
#define EVP_PKEY_ED25519 NID_Ed25519

/* EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of
* the given type. The |type| argument should be one of the |EVP_PKEY_*|
@@ -771,7 +782,7 @@ struct evp_pkey_st {
int type;

union {
char *ptr;
void *ptr;
RSA *rsa;
DSA *dsa;
DH *dh;
@@ -829,5 +840,6 @@ BORINGSSL_MAKE_DELETER(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
#define EVP_R_UNKNOWN_PUBLIC_KEY_TYPE 127
#define EVP_R_UNSUPPORTED_ALGORITHM 128
#define EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE 129
#define EVP_R_NOT_A_PRIVATE_KEY 130

#endif /* OPENSSL_HEADER_EVP_H */

+ 5
- 0
include/openssl/nid.h View File

@@ -4192,6 +4192,11 @@ extern "C" {
#define SN_X25519 "X25519"
#define NID_X25519 948

#define SN_Ed25519 "Ed25519"
#define NID_Ed25519 949
#define OBJ_Ed25519 1L, 3L, 101L, 112L


#if defined(__cplusplus)
} /* extern C */
#endif


Loading…
Cancel
Save