diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-05-26 15:20:38 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-07-17 17:08:01 +0200 |
commit | 650dad4e18f458f60a2cdb43be32356753ed6518 (patch) | |
tree | 308661634af506842f12c709f3ab669d6be1cd7c /lib/x509/key_encode.c | |
parent | f7bc8c6eea0f0fc9d02cfd22fe9fea364061ee37 (diff) | |
download | gnutls-650dad4e18f458f60a2cdb43be32356753ed6518.tar.gz |
Added support for EdDSA (Ed25519) curve keys
This adds support for draft-ietf-curdle-pkix-04.
Resolves #25
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/x509/key_encode.c')
-rw-r--r-- | lib/x509/key_encode.c | 111 |
1 files changed, 83 insertions, 28 deletions
diff --git a/lib/x509/key_encode.c b/lib/x509/key_encode.c index af5e5be5a7..58b1362c58 100644 --- a/lib/x509/key_encode.c +++ b/lib/x509/key_encode.c @@ -128,6 +128,34 @@ _gnutls_x509_write_ecc_pubkey(gnutls_pk_params_st * params, return 0; } +/* + * some x509 certificate functions that relate to MPI parameter + * setting. This writes a raw public key. + * + * Allocates the space used to store the data. + */ +int +_gnutls_x509_write_eddsa_pubkey(gnutls_pk_params_st * params, + gnutls_datum_t * raw) +{ + int ret; + + raw->data = NULL; + raw->size = 0; + + if (params->raw_pub.size == 0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + if (params->flags != GNUTLS_ECC_CURVE_ED25519) + return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); + + ret = _gnutls_set_datum(raw, params->raw_pub.data, params->raw_pub.size); + if (ret < 0) + return gnutls_assert_val(ret); + + return 0; +} + int _gnutls_x509_write_pubkey_params(gnutls_pk_algorithm_t algo, gnutls_pk_params_st * params, @@ -146,8 +174,13 @@ _gnutls_x509_write_pubkey_params(gnutls_pk_algorithm_t algo, return 0; case GNUTLS_PK_RSA_PSS: return _gnutls_x509_write_rsa_pss_params(¶ms->sign, der); - case GNUTLS_PK_EC: + case GNUTLS_PK_ECDSA: return _gnutls_x509_write_ecc_params(params->flags, der); + case GNUTLS_PK_EDDSA_ED25519: + der->data = NULL; + der->size = 0; + + return 0; default: return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); } @@ -164,8 +197,10 @@ _gnutls_x509_write_pubkey(gnutls_pk_algorithm_t algo, case GNUTLS_PK_RSA: case GNUTLS_PK_RSA_PSS: return _gnutls_x509_write_rsa_pubkey(params, der); - case GNUTLS_PK_EC: + case GNUTLS_PK_ECDSA: return _gnutls_x509_write_ecc_pubkey(params, der); + case GNUTLS_PK_EDDSA_ED25519: + return _gnutls_x509_write_eddsa_pubkey(params, der); default: return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); } @@ -615,20 +650,9 @@ _gnutls_asn1_encode_ecc(ASN1_TYPE * c2, gnutls_pk_params_st * params) const char *oid; oid = gnutls_ecc_curve_get_oid(params->flags); - - if (params->params_nr != ECC_PRIVATE_PARAMS || oid == NULL) + if (oid == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - ret = - _gnutls_ecc_ansi_x962_export(params->flags, - params->params[ECC_X], - params->params[ECC_Y], &pubkey); - if (ret < 0) - return gnutls_assert_val(ret); - - /* Ok. Now we have the data. Create the asn1 structures - */ - /* first make sure that no previously allocated data are leaked */ if (*c2 != ASN1_TYPE_EMPTY) { asn1_delete_structure(c2); @@ -650,20 +674,50 @@ _gnutls_asn1_encode_ecc(ASN1_TYPE * c2, gnutls_pk_params_st * params) goto cleanup; } - ret = - _gnutls_x509_write_key_int(*c2, "privateKey", - params->params[ECC_K], 1); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } + if (curve_is_eddsa(params->flags)) { + if (params->raw_pub.size == 0 || params->raw_priv.size == 0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + ret = + asn1_write_value(*c2, "privateKey", params->raw_priv.data, params->raw_priv.size); + if (ret != ASN1_SUCCESS) { + gnutls_assert(); + ret = _gnutls_asn2err(ret); + goto cleanup; + } - if ((ret = - asn1_write_value(*c2, "publicKey", pubkey.data, - pubkey.size * 8)) != ASN1_SUCCESS) { - gnutls_assert(); - ret = _gnutls_asn2err(ret); - goto cleanup; + ret = + asn1_write_value(*c2, "publicKey", params->raw_pub.data, params->raw_pub.size*8); + if (ret != ASN1_SUCCESS) { + gnutls_assert(); + ret = _gnutls_asn2err(ret); + goto cleanup; + } + } else { + if (params->params_nr != ECC_PRIVATE_PARAMS) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + ret = + _gnutls_ecc_ansi_x962_export(params->flags, + params->params[ECC_X], + params->params[ECC_Y], &pubkey); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = + _gnutls_x509_write_key_int(*c2, "privateKey", + params->params[ECC_K], 1); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + if ((ret = + asn1_write_value(*c2, "publicKey", pubkey.data, + pubkey.size * 8)) != ASN1_SUCCESS) { + gnutls_assert(); + ret = _gnutls_asn2err(ret); + goto cleanup; + } } /* write our choice */ @@ -799,7 +853,8 @@ int _gnutls_asn1_encode_privkey(gnutls_pk_algorithm_t pk, ASN1_TYPE * c2, return _gnutls_asn1_encode_rsa(c2, params, compat); case GNUTLS_PK_DSA: return _gnutls_asn1_encode_dsa(c2, params, compat); - case GNUTLS_PK_EC: + case GNUTLS_PK_ECDSA: + case GNUTLS_PK_EDDSA_ED25519: return _gnutls_asn1_encode_ecc(c2, params); default: return GNUTLS_E_UNIMPLEMENTED_FEATURE; |