Browse Source

fix ecc pkcs8 import

toddouska 12 years ago
parent
commit
e82516ad2a
5 changed files with 41 additions and 19 deletions
  1. 5 0
      certs/ecc-keyPkcs8.pem
  2. 1 0
      certs/include.am
  3. 28 16
      ctaocrypt/src/asn.c
  4. 5 0
      cyassl/ctaocrypt/asn.h
  5. 2 3
      src/ssl.c

+ 5 - 0
certs/ecc-keyPkcs8.pem

@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgRbZpAnOcbIWhOFty
+6OjHrMQDjVM1BPpsKNw0jeGoCYyhRANCAAS7M6xMJ1BKxkqlBMM83p8223ItzpTq
+K/rLIAk5LBboYQLpr03TApOaMVuXkiF/8M8Y2pERAjSG6CBYMwuANInY
+-----END PRIVATE KEY-----

+ 1 - 0
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 \

+ 28 - 16
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 (b == ECC_PREFIX_0) {
+        *inOutIdx += 1;
 
-    if (GetLength(input, inOutIdx, &length, inSz) < 0)
-        return ASN_PARSE_E;
+        if (GetLength(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
 
-    /* object id */
-    b = input[*inOutIdx];
-    *inOutIdx += 1;
+        /* object id */
+        b = input[*inOutIdx];
+        *inOutIdx += 1;
     
-    if (b != ASN_OBJECT_ID) 
-        return ASN_OBJECT_ID_E;
+        if (b != ASN_OBJECT_ID) 
+            return ASN_OBJECT_ID_E;
 
-    if (GetLength(input, inOutIdx, &length, inSz) < 0)
-        return ASN_PARSE_E;
+        if (GetLength(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
 
-    while(length--) {
-        oid += input[*inOutIdx];
-        *inOutIdx += 1;
+        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;

+ 5 - 0
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 */

+ 2 - 3
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);