From 03846b2d2d2eaaeaab11e2136c60beaefc5782b2 Mon Sep 17 00:00:00 2001 From: Takashi Kojo Date: Thu, 3 May 2018 19:00:24 +0900 Subject: [PATCH] d2i_RSAPublicKey, d2i_X509_CRL, d2i_X509_CRL_fp, X509_CRL_free, PEM_read_X509_CRL --- src/ssl.c | 228 ++++++++++++++++++++++++++++++++++++++++ tests/api.c | 94 +++++++++++++++++ wolfcrypt/src/asn.c | 10 ++ wolfssl/openssl/ssl.h | 6 ++ wolfssl/ssl.h | 20 +++- wolfssl/wolfcrypt/rsa.h | 3 +- 6 files changed, 357 insertions(+), 4 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 5b449fb5b9..989e9e685b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17971,6 +17971,121 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) } #endif /* NO_CERTS */ +#ifdef HAVE_CRL + +WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl, const unsigned char* in, int len) +{ + WOLFSSL_X509_CRL *newcrl = NULL; + WOLFSSL_CERT_MANAGER *cert= NULL; + int ret ; + + WOLFSSL_ENTER("wolfSSL_X509_CRL_d2i"); + + if(in == NULL){ + WOLFSSL_MSG("Bad argument value"); + return NULL; + } + + newcrl = (WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (newcrl == NULL){ + WOLFSSL_MSG("New CRL allocation failed"); + return NULL; + } + cert = wolfSSL_CertManagerNew(); + if (cert == NULL){ + WOLFSSL_MSG("CertManagerNew failed"); + goto err_exit; + } + if (InitCRL(newcrl, cert) < 0) { + WOLFSSL_MSG("Init tmp CRL failed"); + goto err_exit; + } + ret = BufferLoadCRL(newcrl, in, len, WOLFSSL_FILETYPE_ASN1, 1); + if (ret != WOLFSSL_SUCCESS){ + WOLFSSL_MSG("Buffer Load CRL failed"); + goto err_exit; + } + if(crl){ + *crl = newcrl; + } + goto _exit; + +err_exit: + if(newcrl != NULL) + XFREE(newcrl, NULL, DYNAMIC_TYPE_FILE); + newcrl = NULL; + if(cert != NULL) + wolfSSL_CertManagerFree(cert); +_exit: + return newcrl; +} + +#ifndef NO_FILESYSTEM +WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(WOLFSSL_X509_CRL **crl, XFILE file) +{ + WOLFSSL_X509_CRL *newcrl = NULL; + DerBuffer* der = NULL; + byte *fileBuffer = NULL; + + WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_fp"); + + if (file != XBADFILE) + { + long sz = 0; + + XFSEEK(file, 0, XSEEK_END); + sz = XFTELL(file); + XREWIND(file); + + if (sz < 0) + { + WOLFSSL_MSG("Bad tell on FILE"); + return NULL; + } + + fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE); + if (fileBuffer != NULL) + { + if((long)XFREAD(fileBuffer, 1, sz, file) != sz) + { + WOLFSSL_MSG("File read failed"); + goto err_exit; + } + + newcrl = wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz); + if(newcrl == NULL) + { + WOLFSSL_MSG("X509_CRL failed"); + goto err_exit; + } + } + } + if (crl != NULL) + *crl = newcrl; + + goto _exit; + +err_exit: + if(newcrl != NULL) + XFREE(newcrl, NULL, DYNAMIC_TYPE_FILE); +_exit: + if(der != NULL) + FreeDer(&der); + if(fileBuffer != NULL) + XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE); + return newcrl; +} +#endif + +void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl) +{ + WOLFSSL_ENTER("wolfSSL_X509_CRL_free"); + + FreeCRL(crl, 1); + return; +} +#endif + #ifndef NO_WOLFSSL_STUB WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl) { @@ -27369,6 +27484,57 @@ int wolfSSL_PEM_write_RSA_PUBKEY(FILE *fp, WOLFSSL_RSA *x) #endif /* OPENSSL_EXTRA */ #if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) +WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **r, const unsigned char **pp, long len) +{ + WOLFSSL_RSA *rsa = NULL; + + WOLFSSL_ENTER("d2i_RSAPublicKey"); + if((rsa = wolfSSL_RSA_new()) == NULL){ + WOLFSSL_MSG("RSA_new failed"); + return NULL; + } + + if(wolfSSL_RSA_LoadDer_ex(rsa, *pp, (int)len, WOLFSSL_RSA_LOAD_PUBLIC) + != WOLFSSL_SUCCESS){ + WOLFSSL_MSG("RSA_LoadDer failed"); + return NULL; + } + + *r = rsa; + return rsa; +} + +int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, const unsigned char **pp) +{ + byte *der; + word32 derLen = 165; + int ret; + + WOLFSSL_ENTER("i2d_RSAPublicKey"); + if(pp == NULL) + return WOLFSSL_FATAL_ERROR; + der = (byte*)XMALLOC(derLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (der == NULL) { + ret = WOLFSSL_FATAL_ERROR; + } + if((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetRsaInternal Failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return _REXT_OK; + } + +#if 0 + if((ret = wc_RsaKeyToPublicDer((RsaKey *)rsa->internal, der, derLen)) < 0){ + WOLFSSL_MSG("RsaKeyToPublicDer failed"); + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } +#endif + + *pp = der; + return ret; +} + /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */ int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf, int derSz) { @@ -28352,6 +28518,68 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return x509; } +#ifndef NO_FILESYSTEM + WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(FILE *fp, WOLFSSL_X509_CRL **crl, + pem_password_cb *cb, void *u) + { +#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM) + unsigned char* pem = NULL; + DerBuffer* der = NULL; + int pemSz; + int derSz; + long i = 0, l; + WOLFSSL_X509_CRL* newcrl; + + WOLFSSL_ENTER("wolfSSL_PEM_read_X509_CRL"); + + if (fp == NULL) { + WOLFSSL_LEAVE("wolfSSL_PEM_read_X509_CRL", BAD_FUNC_ARG); + return NULL; + } + /* Read in CRL from file */ + i = XFTELL(fp); + if (i < 0) { + WOLFSSL_LEAVE("wolfSSL_PEM_read_X509_CRL", BAD_FUNC_ARG); + return NULL; + } + + if (XFSEEK(fp, 0, SEEK_END) != 0) + return NULL; + l = XFTELL(fp); + if (l < 0) + return NULL; + if (XFSEEK(fp, i, SEEK_SET) != 0) + return NULL; + pemSz = (int)(l - i); + /* check calculated length */ + if (pemSz < 0) + return NULL; + if((pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM)) == NULL) + return NULL; + + if((int)XFREAD((char *)pem, 1, pemSz, fp) != pemSz) + goto err_exit; + if((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0) + goto err_exit; + + derSz = der->length; + if((newcrl = wolfSSL_d2i_X509_CRL(crl, (const unsigned char *)der->buffer, derSz)) == NULL) + goto err_exit; + return newcrl; + + err_exit: + if(pem != NULL) + XFREE(pem, 0, DYNAMIC_TYPE_PEM); + if(der != NULL) + FreeDer(&der); + return NULL; + + (void)cb; + (void)u; + #endif + + } +#endif /* * bp : bio to read X509 from diff --git a/tests/api.c b/tests/api.c index 11bcbded35..2799abfa9a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -17376,6 +17376,42 @@ static void test_wolfSSL_RSA(void) #endif } +static void test_wolfSSL_RSA_DER(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) + + RSA *rsa; + int i; + + struct + { + const unsigned char *der; + int sz; + } tbl[] = { +#ifdef USE_CERT_BUFFERS_1024 + {client_key_der_1024, sizeof_client_key_der_1024}, + {server_key_der_1024, sizeof_server_key_der_1024}, +#endif +#ifdef USE_CERT_BUFFERS_2048 + {client_key_der_2048, sizeof_client_key_der_2048}, + {server_key_der_2048, sizeof_server_key_der_2048}, +#endif + {NULL, 0} + }; + + printf(testingFmt, "test_wolfSSL_RSA_DER()"); + + for (i = 0; tbl[i].der != NULL; i++) + { + AssertNotNull(d2i_RSAPublicKey(&rsa, &tbl[i].der, tbl[i].sz)); + AssertNotNull(rsa); + RSA_free(rsa); + } + printf(resultFmt, passed); + +#endif +} + static void test_wolfSSL_verify_depth(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) @@ -18570,6 +18606,62 @@ static int test_wc_RNG_GenerateBlock() } #endif +static void test_wolfSSL_X509_CRL(void) +{ +#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) + + X509_CRL *crl; + char pem[][100] = { + "./certs/crl/crl.pem", + "./certs/crl/crl2.pem", + "./certs/crl/caEccCrl.pem", + "./certs/crl/eccCliCRL.pem", + "./certs/crl/eccSrvCRL.pem", + "" + }; + + char der[][100] = { + "./certs/crl/crl.der", + "./certs/crl/crl2.der", + ""}; + + FILE * fp; + int i; + + printf(testingFmt, "test_wolfSSL_X509_CRL"); + + for (i = 0; pem[i][0] != '\0'; i++) + { + AssertNotNull(fp = XFOPEN(pem[i], "rb")); + AssertNotNull(crl = (X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)NULL, NULL, NULL)); + AssertNotNull(crl); + X509_CRL_free(crl); + XFCLOSE(fp); + AssertNotNull(fp = XFOPEN(pem[i], "rb")); + AssertNotNull((X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)&crl, NULL, NULL)); + AssertNotNull(crl); + X509_CRL_free(crl); + XFCLOSE(fp); + } + + for(i = 0; der[i][0] != '\0'; i++){ + AssertNotNull(fp = XFOPEN(der[i], "rb")); + AssertNotNull(crl = (X509_CRL *)d2i_X509_CRL_fp((X509_CRL **)NULL, fp)); + AssertNotNull(crl); + X509_CRL_free(crl); + XFCLOSE(fp); + AssertNotNull(fp = XFOPEN(der[i], "rb")); + AssertNotNull((X509_CRL *)d2i_X509_CRL_fp((X509_CRL **)&crl, fp)); + AssertNotNull(crl); + X509_CRL_free(crl); + XFCLOSE(fp); + } + + printf(resultFmt, passed); +#endif + return; +} + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -18668,6 +18760,7 @@ void ApiTest(void) test_wolfSSL_sk_GENERAL_NAME(); test_wolfSSL_MD4(); test_wolfSSL_RSA(); + test_wolfSSL_RSA_DER(); test_wolfSSL_verify_depth(); test_wolfSSL_HMAC_CTX(); test_wolfSSL_msg_callback(); @@ -18676,6 +18769,7 @@ void ApiTest(void) test_wolfSSL_AES_ecb_encrypt(); test_wolfSSL_SHA256(); test_wolfSSL_X509_get_serialNumber(); + test_wolfSSL_X509_CRL(); /* test the no op functions for compatibility */ test_no_op_functions(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index fafaf3f218..623a24eb49 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -7244,6 +7244,11 @@ const char* const END_PUB_KEY = "-----END PUBLIC KEY-----"; const char* const BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----"; const char* const END_EDDSA_PRIV = "-----END EDDSA PRIVATE KEY-----"; #endif +#ifdef HAVE_CRL + const char *const BEGIN_CRL = "-----BEGIN X509 CRL-----"; + const char* const END_CRL = "-----END X509 CRL-----"; +#endif + int wc_PemGetHeaderFooter(int type, const char** header, const char** footer) @@ -7716,6 +7721,11 @@ int PemToDer(const unsigned char* buff, long longSz, int type, { header = BEGIN_EDDSA_PRIV; footer = END_EDDSA_PRIV; } else +#endif +#ifdef HAVE_CRL + if (type == CRL_TYPE) { + header = BEGIN_CRL; footer = END_CRL; + } else #endif { break; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index e90a5213a9..ad8e8cf67a 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -513,6 +513,11 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define d2i_X509_bio wolfSSL_d2i_X509_bio #define i2d_X509 wolfSSL_i2d_X509 #define d2i_X509 wolfSSL_d2i_X509 +#define d2i_RSAPublicKey wolfSSL_d2i_RSAPublicKey +#define i2d_RSAPublicKey wolfSSL_i2d_RSAPublicKey +#define d2i_X509_CRL wolfSSL_d2i_X509_CRL +#define d2i_X509_CRL_fp wolfSSL_d2i_X509_CRL_fp +#define X509_CRL_free wolfSSL_X509_CRL_free #define SSL_CTX_get_ex_data wolfSSL_CTX_get_ex_data #define SSL_CTX_set_ex_data wolfSSL_CTX_set_ex_data @@ -528,6 +533,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_CTX_get_ex_new_index wolfSSL_CTX_get_ex_new_index #define PEM_read_bio_X509 wolfSSL_PEM_read_bio_X509 #define PEM_read_bio_X509_AUX wolfSSL_PEM_read_bio_X509_AUX +#define PEM_read_X509_CRL wolfSSL_PEM_read_X509_CRL /*#if OPENSSL_API_COMPAT < 0x10100000L*/ #define CONF_modules_free() diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index f425729eec..04c8428ac5 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -164,7 +164,7 @@ typedef struct WOLFSSL_ECDSA_SIG WOLFSSL_ECDSA_SIG; typedef struct WOLFSSL_CIPHER WOLFSSL_CIPHER; typedef struct WOLFSSL_X509_LOOKUP WOLFSSL_X509_LOOKUP; typedef struct WOLFSSL_X509_LOOKUP_METHOD WOLFSSL_X509_LOOKUP_METHOD; -typedef struct WOLFSSL_X509_CRL WOLFSSL_X509_CRL; +typedef struct WOLFSSL_CRL WOLFSSL_X509_CRL; typedef struct WOLFSSL_X509_STORE WOLFSSL_X509_STORE; typedef struct WOLFSSL_X509_VERIFY_PARAM WOLFSSL_X509_VERIFY_PARAM; typedef struct WOLFSSL_BIO WOLFSSL_BIO; @@ -987,8 +987,10 @@ WOLFSSL_API const char* wolfSSL_state_string_long(const WOLFSSL*); WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_generate_key(int, unsigned long, void(*)(int, int, void*), void*); -WOLFSSL_API void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX*, - WOLFSSL_RSA*(*)(WOLFSSL*, int, int)); +WOLFSSL_API WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **r, const unsigned char **pp, long len); +WOLFSSL_API int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *r, const unsigned char **pp); +WOLFSSL_API void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX *, + WOLFSSL_RSA *(*)(WOLFSSL *, int, int)); WOLFSSL_API int wolfSSL_PEM_def_callback(char*, int num, int w, void* key); @@ -1513,6 +1515,11 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const unsigned char* in, int len); WOLFSSL_API int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out); +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL **crl, + const unsigned char *in, int len); +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(WOLFSSL_X509_CRL **crl, XFILE file); +WOLFSSL_API void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl); + #ifndef NO_FILESYSTEM #ifndef NO_STDIO_FILESYSTEM WOLFSSL_API WOLFSSL_X509* @@ -2538,6 +2545,13 @@ WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *p WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX (WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL **crl, + const unsigned char *in, int len); +#ifndef NO_FILESYSTEM +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(WOLFSSL_X509_CRL **crl, XFILE file); +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_PEM_read_X509_CRL(FILE *fp, WOLFSSL_X509_CRL **x, + pem_password_cb *cb, void *u); +#endif /*lighttp compatibility */ diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 5cbc76770b..a11b016eb4 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -247,8 +247,9 @@ WOLFSSL_API int wc_RsaExportKey(RsaKey* key, byte* p, word32* pSz, byte* q, word32* qSz); +WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey*, byte* output, word32 inLen); + #ifdef WOLFSSL_KEY_GEN - WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey*, byte* output, word32 inLen); WOLFSSL_API int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng); WOLFSSL_API int wc_CheckProbablePrime(const byte* p, word32 pSz, const byte* q, word32 qSz,