On 2013/03/13 09:52, Jason Hall wrote:
> Reyk,
>
> I've taken the liberty of patching ca.c, crypto.c, ikev2.h, parse.y,
> iked.8 and iked.conf.5. I'm no expert on this, but this seems to
> work for me. SAs and Flows are established, it hasn't crashed, and
> I'm passing data.
>
> Let me know what you think.
Looking at received: headers it looks like you're in the US - if so,
and if my understanding of the restrictions is correct, I don't think
we would be able to use this diff directly.
> Thanks,
> -Jason
>
> diff -u sbin/iked.orig/ca.c sbin/iked/ca.c
> --- sbin/iked.orig/ca.c Tue Mar 12 18:15:44 2013
> +++ sbin/iked/ca.c Wed Mar 13 09:17:37 2013
> @@ -346,6 +346,9 @@
> case IKEV2_CERT_RSA_KEY:
> ret = ca_validate_pubkey(env, &id, ptr, len);
> break;
> + case IKEV2_CERT_EC_KEY:
> + ret = ca_validate_pubkey(env, &id, ptr, len);
> + break;
> default:
> log_debug("%s: unsupported cert type %d", __func__, type);
> ret = -1;
> @@ -754,6 +757,7 @@
> int len;
> u_int8_t *d;
> RSA *rsa;
> + EC_KEY *eckey;
>
> switch (key->type) {
> case EVP_PKEY_RSA:
> @@ -776,6 +780,26 @@
>
> id->id_type = IKEV2_CERT_RSA_KEY;
> break;
> + case EVP_PKEY_EC:
> + id->id_type = 0;
> + id->id_offset = 0;
> + ibuf_release(id->id_buf);
> +
> + if ((eckey = EVP_PKEY_get1_EC_KEY(key)) == NULL)
> + return (-1);
> + if ((len = i2d_ECPrivateKey(eckey, NULL)) <= 0)
> + return (-1);
> + if ((id->id_buf = ibuf_new(NULL, len)) == NULL)
> + return (-1);
> +
> + d = ibuf_data(id->id_buf);
> + if (i2d_ECPrivateKey(eckey, &d) != len) {
> + ibuf_release(id->id_buf);
> + return (-1);
> + }
> +
> + id->id_type = IKEV2_CERT_EC_KEY;
> + break;
> default:
> log_debug("%s: unsupported key type %d", __func__, key->type);
> return (-1);
> @@ -819,6 +843,7 @@
> {
> BIO *rawcert = NULL;
> RSA *rsa = NULL;
> + EC_KEY *eckey = NULL;
> EVP_PKEY *peerkey = NULL, *localkey = NULL;
> int ret = -1;
> FILE *fp = NULL;
> @@ -856,12 +881,16 @@
> if ((rawcert = BIO_new_mem_buf(data, len)) == NULL)
> goto done;
>
> - if ((rsa = d2i_RSAPublicKey_bio(rawcert, NULL)) == NULL)
> - goto sslerr;
> + if ((rsa = d2i_RSAPublicKey_bio(rawcert, NULL)) == NULL) {
> + if ((eckey = d2i_EC_PUBKEY_bio(rawcert, NULL )) == NULL)
> + goto sslerr;
> + }
> if ((peerkey = EVP_PKEY_new()) == NULL)
> goto sslerr;
> - if (!EVP_PKEY_set1_RSA(peerkey, rsa))
> - goto sslerr;
> + if (!EVP_PKEY_set1_RSA(peerkey, rsa)) {
> + if (!EVP_PKEY_set1_EC_KEY(peerkey, eckey))
> + goto sslerr;
> + }
> }
>
> lc_string(idstr);
> @@ -892,6 +921,8 @@
> EVP_PKEY_free(peerkey);
> if (rsa != NULL)
> RSA_free(rsa);
> + if (eckey != NULL)
> + EC_KEY_free(eckey);
> if (rawcert != NULL)
> BIO_free(rawcert);
>
> diff -u sbin/iked.orig/crypto.c sbin/iked/crypto.c
> --- sbin/iked.orig/crypto.c Tue Mar 12 18:15:44 2013
> +++ sbin/iked/crypto.c Wed Mar 13 09:17:37 2013
> @@ -542,6 +542,7 @@
> BIO *rawcert = NULL;
> X509 *cert = NULL;
> RSA *rsa = NULL;
> + EC_KEY *eckey = NULL;
> EVP_PKEY *pkey = NULL;
>
> ibuf_release(dsa->dsa_keydata);
> @@ -576,6 +577,25 @@
> if ((pkey = EVP_PKEY_new()) == NULL)
> goto sslerr;
> if (!EVP_PKEY_set1_RSA(pkey, rsa))
> + goto sslerr;
> +
> + dsa->dsa_cert = NULL;
> + dsa->dsa_key = pkey;
> + break;
> + case IKEV2_CERT_EC_KEY:
> + if (dsa->dsa_sign) {
> + if ((eckey = d2i_ECPrivateKey_bio(rawcert,
> + NULL)) == NULL)
> + goto sslerr;
> + } else {
> + if ((eckey = d2i_EC_PUBKEY_bio(rawcert,
> + NULL)) == NULL)
> + goto sslerr;
> + }
> +
> + if ((pkey = EVP_PKEY_new()) == NULL)
> + goto sslerr;
> + if (!EVP_PKEY_set1_EC_KEY(pkey, eckey))
> goto sslerr;
>
> dsa->dsa_cert = NULL;
> diff -u sbin/iked.orig/iked.8 sbin/iked/iked.8
> --- sbin/iked.orig/iked.8 Tue Mar 12 18:15:45 2013
> +++ sbin/iked/iked.8 Wed Mar 13 09:17:37 2013
> @@ -46,7 +46,7 @@
> .Xr isakmpd 8 .
> .Pp
> .Nm
> -supports mutual authentication using RSA public keys and X.509
> certificates.
> +supports mutual authentication using RSA, or ECDSA, public keys and
> X.509 certificates.
> See the
> .Sx FILES
> section below and
> diff -u sbin/iked.orig/iked.conf.5 sbin/iked/iked.conf.5
> --- sbin/iked.orig/iked.conf.5 Tue Mar 12 18:15:45 2013
> +++ sbin/iked/iked.conf.5 Wed Mar 13 09:17:37 2013
> @@ -472,6 +472,10 @@
> .It Ic rsa
> Use RSA public key authentication.
> This is the default mode if no option is specified.
> +.It Ic ecdsa-256
> +.It Ic ecdsa-384
> +.It Ic ecdsa-512
> +Use ECDSA public key authentication.
> .El
> .It Ic tag Ar string
> Add a
> diff -u sbin/iked.orig/ikev2.h sbin/iked/ikev2.h
> --- sbin/iked.orig/ikev2.h Tue Mar 12 18:15:45 2013
> +++ sbin/iked/ikev2.h Wed Mar 13 09:37:27 2013
> @@ -374,6 +374,7 @@
> #define IKEV2_CERT_HASHURL_X509 12 /* RFC4306 */
> #define IKEV2_CERT_HASHURL_X509_BUNDLE 13 /* RFC4306 */
> #define IKEV2_CERT_OCSP 14 /* RFC4806 */
> +#define IKEV2_CERT_EC_KEY 201 /* UNKNOWN RFC */
>
> extern struct iked_constmap ikev2_cert_map[];
>
> diff -u sbin/iked.orig/parse.y sbin/iked/parse.y
> --- sbin/iked.orig/parse.y Tue Mar 12 18:15:45 2013
> +++ sbin/iked/parse.y Wed Mar 13 09:17:37 2013
> @@ -365,6 +365,7 @@
> %}
>
> %token FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK PORT
> +%token ECDSA_256 ECDSA_384 ECDSA_512
> %token FILENAME AUTHXF PRFXF ENCXF ERROR IKEV2 IKESA CHILDSA
> %token PASSIVE ACTIVE ANY TAG TAP PROTO LOCAL GROUP NAME CONFIG EAP
> USER
> %token IKEV1 FLOW SA TCPMD5 TUNNEL TRANSPORT COUPLE DECOUPLE SET
> @@ -791,6 +792,18 @@
> $$.auth_method = IKEV2_AUTH_RSA_SIG;
> $$.auth_length = 0;
> }
> + | ECDSA_256 {
> + $$.auth_method = IKEV2_AUTH_ECDSA_256;
> + $$.auth_length = 0;
> + }
> + | ECDSA_384 {
> + $$.auth_method = IKEV2_AUTH_ECDSA_384;
> + $$.auth_length = 0;
> + }
> + | ECDSA_512 {
> + $$.auth_method = IKEV2_AUTH_ECDSA_512;
> + $$.auth_length = 0;
> + }
> | PSK keyspec {
> memcpy(&$$, &$2, sizeof($$));
> $$.auth_method = IKEV2_AUTH_SHARED_KEY_MIC;
> @@ -1065,6 +1078,9 @@
> { "default", DEFAULT },
> { "dstid", DSTID },
> { "eap", EAP },
> + { "ecdsa-256", ECDSA_256 },
> + { "ecdsa-384", ECDSA_384 },
> + { "ecdsa-512", ECDSA_512 },
> { "enc", ENCXF },
> { "esp", ESP },
> { "file", FILENAME },
> diff -u sbin/iked.orig/ca.c sbin/iked/ca.c
> --- sbin/iked.orig/ca.c Tue Mar 12 18:15:44 2013
> +++ sbin/iked/ca.c Wed Mar 13 09:17:37 2013
> @@ -346,6 +346,9 @@
> case IKEV2_CERT_RSA_KEY:
> ret = ca_validate_pubkey(env, &id, ptr, len);
> break;
> + case IKEV2_CERT_EC_KEY:
> + ret = ca_validate_pubkey(env, &id, ptr, len);
> + break;
> default:
> log_debug("%s: unsupported cert type %d", __func__, type);
> ret = -1;
> @@ -754,6 +757,7 @@
> int len;
> u_int8_t *d;
> RSA *rsa;
> + EC_KEY *eckey;
>
> switch (key->type) {
> case EVP_PKEY_RSA:
> @@ -776,6 +780,26 @@
>
> id->id_type = IKEV2_CERT_RSA_KEY;
> break;
> + case EVP_PKEY_EC:
> + id->id_type = 0;
> + id->id_offset = 0;
> + ibuf_release(id->id_buf);
> +
> + if ((eckey = EVP_PKEY_get1_EC_KEY(key)) == NULL)
> + return (-1);
> + if ((len = i2d_ECPrivateKey(eckey, NULL)) <= 0)
> + return (-1);
> + if ((id->id_buf = ibuf_new(NULL, len)) == NULL)
> + return (-1);
> +
> + d = ibuf_data(id->id_buf);
> + if (i2d_ECPrivateKey(eckey, &d) != len) {
> + ibuf_release(id->id_buf);
> + return (-1);
> + }
> +
> + id->id_type = IKEV2_CERT_EC_KEY;
> + break;
> default:
> log_debug("%s: unsupported key type %d", __func__, key->type);
> return (-1);
> @@ -819,6 +843,7 @@
> {
> BIO *rawcert = NULL;
> RSA *rsa = NULL;
> + EC_KEY *eckey = NULL;
> EVP_PKEY *peerkey = NULL, *localkey = NULL;
> int ret = -1;
> FILE *fp = NULL;
> @@ -856,12 +881,16 @@
> if ((rawcert = BIO_new_mem_buf(data, len)) == NULL)
> goto done;
>
> - if ((rsa = d2i_RSAPublicKey_bio(rawcert, NULL)) == NULL)
> - goto sslerr;
> + if ((rsa = d2i_RSAPublicKey_bio(rawcert, NULL)) == NULL) {
> + if ((eckey = d2i_EC_PUBKEY_bio(rawcert, NULL )) == NULL)
> + goto sslerr;
> + }
> if ((peerkey = EVP_PKEY_new()) == NULL)
> goto sslerr;
> - if (!EVP_PKEY_set1_RSA(peerkey, rsa))
> - goto sslerr;
> + if (!EVP_PKEY_set1_RSA(peerkey, rsa)) {
> + if (!EVP_PKEY_set1_EC_KEY(peerkey, eckey))
> + goto sslerr;
> + }
> }
>
> lc_string(idstr);
> @@ -892,6 +921,8 @@
> EVP_PKEY_free(peerkey);
> if (rsa != NULL)
> RSA_free(rsa);
> + if (eckey != NULL)
> + EC_KEY_free(eckey);
> if (rawcert != NULL)
> BIO_free(rawcert);
>
> diff -u sbin/iked.orig/crypto.c sbin/iked/crypto.c
> --- sbin/iked.orig/crypto.c Tue Mar 12 18:15:44 2013
> +++ sbin/iked/crypto.c Wed Mar 13 09:17:37 2013
> @@ -542,6 +542,7 @@
> BIO *rawcert = NULL;
> X509 *cert = NULL;
> RSA *rsa = NULL;
> + EC_KEY *eckey = NULL;
> EVP_PKEY *pkey = NULL;
>
> ibuf_release(dsa->dsa_keydata);
> @@ -576,6 +577,25 @@
> if ((pkey = EVP_PKEY_new()) == NULL)
> goto sslerr;
> if (!EVP_PKEY_set1_RSA(pkey, rsa))
> + goto sslerr;
> +
> + dsa->dsa_cert = NULL;
> + dsa->dsa_key = pkey;
> + break;
> + case IKEV2_CERT_EC_KEY:
> + if (dsa->dsa_sign) {
> + if ((eckey = d2i_ECPrivateKey_bio(rawcert,
> + NULL)) == NULL)
> + goto sslerr;
> + } else {
> + if ((eckey = d2i_EC_PUBKEY_bio(rawcert,
> + NULL)) == NULL)
> + goto sslerr;
> + }
> +
> + if ((pkey = EVP_PKEY_new()) == NULL)
> + goto sslerr;
> + if (!EVP_PKEY_set1_EC_KEY(pkey, eckey))
> goto sslerr;
>
> dsa->dsa_cert = NULL;
> diff -u sbin/iked.orig/iked.8 sbin/iked/iked.8
> --- sbin/iked.orig/iked.8 Tue Mar 12 18:15:45 2013
> +++ sbin/iked/iked.8 Wed Mar 13 09:17:37 2013
> @@ -46,7 +46,7 @@
> .Xr isakmpd 8 .
> .Pp
> .Nm
> -supports mutual authentication using RSA public keys and X.509 certificates.
> +supports mutual authentication using RSA, or ECDSA, public keys and X.509
> certificates.
> See the
> .Sx FILES
> section below and
> diff -u sbin/iked.orig/iked.conf.5 sbin/iked/iked.conf.5
> --- sbin/iked.orig/iked.conf.5 Tue Mar 12 18:15:45 2013
> +++ sbin/iked/iked.conf.5 Wed Mar 13 09:17:37 2013
> @@ -472,6 +472,10 @@
> .It Ic rsa
> Use RSA public key authentication.
> This is the default mode if no option is specified.
> +.It Ic ecdsa-256
> +.It Ic ecdsa-384
> +.It Ic ecdsa-512
> +Use ECDSA public key authentication.
> .El
> .It Ic tag Ar string
> Add a
> diff -u sbin/iked.orig/ikev2.h sbin/iked/ikev2.h
> --- sbin/iked.orig/ikev2.h Tue Mar 12 18:15:45 2013
> +++ sbin/iked/ikev2.h Wed Mar 13 09:37:27 2013
> @@ -374,6 +374,7 @@
> #define IKEV2_CERT_HASHURL_X509 12 /* RFC4306 */
> #define IKEV2_CERT_HASHURL_X509_BUNDLE 13 /* RFC4306 */
> #define IKEV2_CERT_OCSP 14 /* RFC4806 */
> +#define IKEV2_CERT_EC_KEY 201 /* UNKNOWN RFC */
>
> extern struct iked_constmap ikev2_cert_map[];
>
> diff -u sbin/iked.orig/parse.y sbin/iked/parse.y
> --- sbin/iked.orig/parse.y Tue Mar 12 18:15:45 2013
> +++ sbin/iked/parse.y Wed Mar 13 09:17:37 2013
> @@ -365,6 +365,7 @@
> %}
>
> %token FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK PORT
> +%token ECDSA_256 ECDSA_384 ECDSA_512
> %token FILENAME AUTHXF PRFXF ENCXF ERROR IKEV2 IKESA CHILDSA
> %token PASSIVE ACTIVE ANY TAG TAP PROTO LOCAL GROUP NAME CONFIG EAP
> USER
> %token IKEV1 FLOW SA TCPMD5 TUNNEL TRANSPORT COUPLE DECOUPLE SET
> @@ -791,6 +792,18 @@
> $$.auth_method = IKEV2_AUTH_RSA_SIG;
> $$.auth_length = 0;
> }
> + | ECDSA_256 {
> + $$.auth_method = IKEV2_AUTH_ECDSA_256;
> + $$.auth_length = 0;
> + }
> + | ECDSA_384 {
> + $$.auth_method = IKEV2_AUTH_ECDSA_384;
> + $$.auth_length = 0;
> + }
> + | ECDSA_512 {
> + $$.auth_method = IKEV2_AUTH_ECDSA_512;
> + $$.auth_length = 0;
> + }
> | PSK keyspec {
> memcpy(&$$, &$2, sizeof($$));
> $$.auth_method = IKEV2_AUTH_SHARED_KEY_MIC;
> @@ -1065,6 +1078,9 @@
> { "default", DEFAULT },
> { "dstid", DSTID },
> { "eap", EAP },
> + { "ecdsa-256", ECDSA_256 },
> + { "ecdsa-384", ECDSA_384 },
> + { "ecdsa-512", ECDSA_512 },
> { "enc", ENCXF },
> { "esp", ESP },
> { "file", FILENAME },