diff --git a/certs/ecc-keyPkcs8.pem b/certs/ecc-keyPkcs8.pem new file mode 100644 index 000000000..ca03d9803 --- /dev/null +++ b/certs/ecc-keyPkcs8.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgRbZpAnOcbIWhOFty +6OjHrMQDjVM1BPpsKNw0jeGoCYyhRANCAAS7M6xMJ1BKxkqlBMM83p8223ItzpTq +K/rLIAk5LBboYQLpr03TApOaMVuXkiF/8M8Y2pERAjSG6CBYMwuANInY +-----END PRIVATE KEY----- diff --git a/certs/include.am b/certs/include.am index d9bb41520..5f6e4c563 100644 --- a/certs/include.am +++ b/certs/include.am @@ -9,6 +9,7 @@ certs_DATA+= \ certs/client-keyEnc.pem \ certs/client-key.pem \ certs/ecc-key.pem \ + certs/ecc-keyPkcs8.pem \ certs/ntru-cert.pem \ certs/dh2048.pem \ certs/server-cert.pem \ diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 78137295b..f239fb15b 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -518,6 +518,14 @@ int ToTraditional(byte* input, word32 sz) if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) return ASN_PARSE_E; + + if (input[inOutIdx] == ASN_OBJECT_ID) { + /* pkcs8 ecc uses slightly different format */ + inOutIdx++; /* past id */ + if (GetLength(input, &inOutIdx, &length, sz) < 0) + return ASN_PARSE_E; + inOutIdx += length; /* over sub id, key input will verify */ + } if (input[inOutIdx++] != ASN_OCTET_STRING) return ASN_PARSE_E; @@ -3610,33 +3618,37 @@ int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, XMEMCPY(priv, &input[*inOutIdx], privSz); *inOutIdx += length; - /* prefix 0 */ + /* prefix 0, may have */ b = input[*inOutIdx]; - *inOutIdx += 1; - - if (GetLength(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - /* object id */ - b = input[*inOutIdx]; - *inOutIdx += 1; - - if (b != ASN_OBJECT_ID) - return ASN_OBJECT_ID_E; - - if (GetLength(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - while(length--) { - oid += input[*inOutIdx]; + if (b == ECC_PREFIX_0) { *inOutIdx += 1; + + if (GetLength(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + /* object id */ + b = input[*inOutIdx]; + *inOutIdx += 1; + + if (b != ASN_OBJECT_ID) + return ASN_OBJECT_ID_E; + + if (GetLength(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + while(length--) { + oid += input[*inOutIdx]; + *inOutIdx += 1; + } + if (CheckCurve(oid) < 0) + return ECC_CURVE_OID_E; } - if (CheckCurve(oid) < 0) - return ECC_CURVE_OID_E; /* prefix 1 */ b = input[*inOutIdx]; *inOutIdx += 1; + if (b != ECC_PREFIX_1) + return ASN_ECC_KEY_E; if (GetLength(input, inOutIdx, &length, inSz) < 0) return ASN_PARSE_E; diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index 71d00859b..8fd2a16eb 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -93,6 +93,11 @@ enum ENCRYPTION_TYPES { RC4_TYPE = 2 }; +enum ECC_TYPES { + ECC_PREFIX_0 = 160, + ECC_PREFIX_1 = 161 +}; + enum Misc_ASN { ASN_NAME_MAX = 256, MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */ diff --git a/src/ssl.c b/src/ssl.c index 48786908b..3a96c40ca 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -906,9 +906,8 @@ int AddCA(CYASSL_CTX* ctx, buffer der) InitRsaKey(&key, 0); if (RsaPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) { #ifdef HAVE_ECC - /* could have DER ECC, no easy way to tell */ - if (format == SSL_FILETYPE_ASN1) - eccKey = 1; /* try it out */ + /* could have DER ECC (or pkcs8 ecc), no easy way to tell */ + eccKey = 1; /* so try it out */ #endif if (!eccKey) { FreeRsaKey(&key);