Browse Source

add wc_GetPkcs8TraditionalOffset()

Chris Conlon 7 years ago
parent
commit
efc2bb43d2
5 changed files with 111 additions and 12 deletions
  1. BIN
      certs/server-keyPkcs8.der
  2. 53 0
      tests/api.c
  3. 53 12
      wolfcrypt/src/asn.c
  4. 2 0
      wolfssl/wolfcrypt/asn.h
  5. 3 0
      wolfssl/wolfcrypt/asn_public.h

BIN
certs/server-keyPkcs8.der


+ 53 - 0
tests/api.c

@@ -36,6 +36,9 @@
 #ifdef HAVE_ECC
     #include <wolfssl/wolfcrypt/ecc.h>   /* wc_ecc_fp_free */
 #endif
+#ifndef NO_ASN
+    #include <wolfssl/wolfcrypt/asn_public.h>
+#endif
 #include <wolfssl/error-ssl.h>
 
 #include <stdlib.h>
@@ -3026,6 +3029,52 @@ static void test_wolfSSL_BIO(void)
 }
 
 
+/*----------------------------------------------------------------------------*
+ | wolfCrypt ASN
+ *----------------------------------------------------------------------------*/
+
+static void test_wc_GetPkcs8TraditionalOffset(void)
+{
+#if !defined(NO_ASN) && !defined(NO_FILESYSTEM)
+    int length, derSz;
+    word32 inOutIdx;
+    const char* path = "./certs/server-keyPkcs8.der";
+    FILE* file;
+    byte der[2048];
+
+    printf(testingFmt, "wc_GetPkcs8TraditionalOffset");
+
+    file = fopen(path, "rb");
+    AssertNotNull(file);
+    derSz = (int)fread(der, 1, sizeof(der), file);
+    fclose(file);
+
+    /* valid case */
+    inOutIdx = 0;
+    length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx, derSz);
+    AssertIntGT(length, 0);
+
+    /* inOutIdx > sz */
+    inOutIdx = 4000;
+    length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx, derSz);
+    AssertIntEQ(length, BAD_FUNC_ARG);
+
+    /* null input */
+    inOutIdx = 0;
+    length = wc_GetPkcs8TraditionalOffset(NULL, &inOutIdx, 0);
+    AssertIntEQ(length, BAD_FUNC_ARG);
+
+    /* invalid input, fill buffer with 1's */
+    XMEMSET(der, 1, sizeof(der));
+    inOutIdx = 0;
+    length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx, derSz);
+    AssertIntEQ(length, ASN_PARSE_E);
+
+    printf(resultFmt, passed);
+#endif /* NO_ASN */
+}
+
+
 /*----------------------------------------------------------------------------*
  | Main
  *----------------------------------------------------------------------------*/
@@ -3086,6 +3135,10 @@ void ApiTest(void)
     test_wolfSSL_BIO();
 
     AssertIntEQ(test_wolfSSL_Cleanup(), SSL_SUCCESS);
+
+    /* wolfCrypt ASN tests */
+    test_wc_GetPkcs8TraditionalOffset();
+
     printf(" End API Tests\n");
 
 }

+ 53 - 12
wolfcrypt/src/asn.c

@@ -1520,41 +1520,82 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
 #endif /* HAVE_USER_RSA */
 #endif /* NO_RSA */
 
-/* Remove PKCS8 header, move beginning of traditional to beginning of input */
-int ToTraditional(byte* input, word32 sz)
+/* Remove PKCS8 header, place inOutIdx at beginning of traditional,
+ * return traditional length on success, negative on error */
+int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
 {
-    word32 inOutIdx = 0, oid;
+    word32 idx, oid;
     int    version, length;
 
-    if (GetSequence(input, &inOutIdx, &length, sz) < 0)
+    if (input == NULL || inOutIdx == NULL)
+        return BAD_FUNC_ARG;
+
+    idx = *inOutIdx;
+
+    if (GetSequence(input, &idx, &length, sz) < 0)
         return ASN_PARSE_E;
 
-    if (GetMyVersion(input, &inOutIdx, &version, sz) < 0)
+    if (GetMyVersion(input, &idx, &version, sz) < 0)
         return ASN_PARSE_E;
 
-    if (GetAlgoId(input, &inOutIdx, &oid, oidKeyType, sz) < 0)
+    if (GetAlgoId(input, &idx, &oid, oidKeyType, sz) < 0)
         return ASN_PARSE_E;
 
-    if (input[inOutIdx] == ASN_OBJECT_ID) {
+    if (input[idx] == ASN_OBJECT_ID) {
         /* pkcs8 ecc uses slightly different format */
-        inOutIdx++;  /* past id */
-        if (GetLength(input, &inOutIdx, &length, sz) < 0)
+        idx++;  /* past id */
+        if (GetLength(input, &idx, &length, sz) < 0)
             return ASN_PARSE_E;
-        inOutIdx += length;  /* over sub id, key input will verify */
+        idx += length;  /* over sub id, key input will verify */
     }
 
-    if (input[inOutIdx++] != ASN_OCTET_STRING)
+    if (input[idx++] != ASN_OCTET_STRING)
         return ASN_PARSE_E;
 
-    if (GetLength(input, &inOutIdx, &length, sz) < 0)
+    if (GetLength(input, &idx, &length, sz) < 0)
         return ASN_PARSE_E;
 
+    *inOutIdx = idx;
+
+    return length;
+}
+
+/* Remove PKCS8 header, move beginning of traditional to beginning of input */
+int ToTraditional(byte* input, word32 sz)
+{
+    word32 inOutIdx = 0;
+    int    length;
+
+    if (input == NULL)
+        return BAD_FUNC_ARG;
+
+    length = ToTraditionalInline(input, &inOutIdx, sz);
+    if (length < 0)
+        return length;
+
     XMEMMOVE(input, input + inOutIdx, length);
 
     return length;
 }
 
 
+/* find beginning of traditional key inside PKCS#8 unencrypted buffer
+ * return traditional length on success, with inOutIdx at beginning of
+ * traditional
+ * return negative on failure/error */
+int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
+{
+    int length;
+
+    if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
+        return BAD_FUNC_ARG;
+
+    length = ToTraditionalInline(input, inOutIdx, sz);
+
+    return length;
+}
+
+
 /* check that the private key is a pair for the public key in certificate
  * return 1 (true) on match
  * return 0 or negative value on failure/error

+ 2 - 0
wolfssl/wolfcrypt/asn.h

@@ -680,6 +680,8 @@ WOLFSSL_LOCAL void    FreeTrustedPeerTable(TrustedPeerCert**, int, void*);
 #endif /* WOLFSSL_TRUST_PEER_CERT */
 
 WOLFSSL_ASN_API int ToTraditional(byte* buffer, word32 length);
+WOLFSSL_LOCAL int ToTraditionalInline(const byte* input, word32* inOutIdx,
+                                      word32 length);
 WOLFSSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*,int);
 WOLFSSL_LOCAL int DecryptContent(byte* input, word32 sz,const char* psw,int pswSz);
 

+ 3 - 0
wolfssl/wolfcrypt/asn_public.h

@@ -268,6 +268,9 @@ WOLFSSL_API word32 wc_EncodeSignature(byte* out, const byte* digest,
                                       word32 digSz, int hashOID);
 WOLFSSL_API int wc_GetCTC_HashOID(int type);
 
+WOLFSSL_API int wc_GetPkcs8TraditionalOffset(byte* input,
+                                             word32* inOutIdx, word32 sz);
+
 /* Time */
 /* Returns seconds (Epoch/UTC)
  * timePtr: is "time_t", which is typically "long"