diff --git a/src/ssl.c b/src/ssl.c index 81c747810..82a5feb2d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -26006,6 +26006,72 @@ WOLFSSL_API int i2t_ASN1_OBJECT(char *buf, int buf_len, WOLFSSL_ASN1_OBJECT *a) } #endif +/** + * Parse an ASN1 encoded input and output information about the parsed object + * @param in ASN1 encoded data. *in is moved to the value of the ASN1 object + * @param len Length of parsed ASN1 object + * @param tag Tag value of parsed ASN1 object + * @param class Class of parsed ASN1 object + * @param inLen Length of *in buffer + * @return int Depends on which bits are set in the returned int: + * 0x80 an error occured during parsing + * 0x20 parsed object is constructed + * 0x01 the parsed object length is infinite + */ +int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, + int *class, long inLen) +{ + word32 inOutIdx = 0; + int l; + byte t; + int ret = 0x80; + + WOLFSSL_ENTER("wolfSSL_ASN1_get_object"); + + if (!in || !*in || !len || !tag || !class || inLen == 0) { + WOLFSSL_MSG("Bad parameter"); + return ret; + } + + if (GetASNTag(*in, &inOutIdx, &t, inLen) != 0) { + WOLFSSL_MSG("GetASNTag error"); + return ret; + } + + if (GetLength(*in, &inOutIdx, &l, inLen) < 0) { + WOLFSSL_MSG("GetLength error"); + return ret; + } + + *tag = t & 0x1F; /* Tag number is 5 lsb */ + *class = t & 0xC0; /* Class is 2 msb */ + *len = l; + ret = t & ASN_CONSTRUCTED; + + if (l > inLen - inOutIdx) { + /* Still return other values but indicate error in msb */ + ret |= 0x80; + } + + *in += inOutIdx; + return ret; +} + +#ifndef NO_WOLFSSL_STUB +WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, + const unsigned char **pp, long len) +{ + (void)a; + (void)pp; + (void)len; + + WOLFSSL_ENTER("wolfSSL_c2i_ASN1_OBJECT"); + WOLFSSL_STUB("c2i_ASN1_OBJECT"); + + return NULL; +} +#endif + #ifndef NO_BIO /* Return number of bytes written to BIO on success. 0 on failure. */ WOLFSSL_API int wolfSSL_i2a_ASN1_OBJECT(WOLFSSL_BIO *bp, diff --git a/tests/api.c b/tests/api.c index 3f9a2f7a3..e6b5315ea 100644 --- a/tests/api.c +++ b/tests/api.c @@ -38750,6 +38750,42 @@ static void test_wolfSSL_ASN1_STRING_print(void){ #endif /* !NO_BIO */ +static void test_wolfSSL_ASN1_get_object(void) +{ +#ifdef OPENSSL_EXTRA + const unsigned char* derBuf = cliecc_cert_der_256; + int len = sizeof_cliecc_cert_der_256; + long asnLen = 0; + int tag = 0, class = 0; + + printf(testingFmt, "wolfSSL_ASN1_get_object()"); + + /* Read a couple TLV triplets and make sure they match the expected values */ + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, len) & 0x80, 0); + AssertIntEQ(asnLen, 831); + AssertIntEQ(tag, 0x10); + AssertIntEQ(class, 0); + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); + AssertIntEQ(asnLen, 741); + AssertIntEQ(tag, 0x10); + AssertIntEQ(class, 0); + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); + AssertIntEQ(asnLen, 3); + AssertIntEQ(tag, 0); + AssertIntEQ(class, 0x80); + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); + AssertIntEQ(asnLen, 1); + AssertIntEQ(tag, 0x2); + AssertIntEQ(class, 0); + + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA */ +} + static void test_wolfSSL_RSA_verify() { #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && \ @@ -39659,6 +39695,7 @@ void ApiTest(void) test_wolfSSL_RSA_print(); test_wolfSSL_ASN1_STRING_print(); #endif + test_wolfSSL_ASN1_get_object(); test_openssl_generate_key_and_cert(); test_wolfSSL_EC_get_builtin_curves(); diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index f9f806b89..f2a0c21e5 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -32,6 +32,8 @@ #define ASN1_STRING_set wolfSSL_ASN1_STRING_set #define ASN1_STRING_free wolfSSL_ASN1_STRING_free +#define ASN1_get_object wolfSSL_ASN1_get_object + #define V_ASN1_INTEGER 0x02 #define V_ASN1_OCTET_STRING 0x04 /* tag for ASN1_OCTET_STRING */ #define V_ASN1_NEG 0x100 @@ -83,6 +85,9 @@ WOLFSSL_API WOLFSSL_ASN1_INTEGER *wolfSSL_BN_to_ASN1_INTEGER( WOLFSSL_API void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value); +WOLFSSL_API int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, + int *class, long inLen); + #ifdef OPENSSL_ALL /* IMPLEMENT_ASN1_FUNCTIONS is strictly for external use only. Internally * we don't use this. Some projects use OpenSSL to implement ASN1 types and