diff --git a/include/polarssl/x509_csr.h b/include/polarssl/x509_csr.h index deac88fde..bbe6beca5 100644 --- a/include/polarssl/x509_csr.h +++ b/include/polarssl/x509_csr.h @@ -85,7 +85,19 @@ x509write_csr; #if defined(POLARSSL_X509_CSR_PARSE_C) /** - * \brief Load a Certificate Signing Request (CSR) + * \brief Load a Certificate Signing Request (CSR) in DER format + * + * \param csr CSR context to fill + * \param buf buffer holding the CRL data + * \param buflen size of the buffer + * + * \return 0 if successful, or a specific X509 error code + */ +int x509_csr_parse_der( x509_csr *csr, + const unsigned char *buf, size_t buflen ); + +/** + * \brief Load a Certificate Signing Request (CSR), DER or PEM format * * \param csr CSR context to fill * \param buf buffer holding the CRL data diff --git a/library/x509_csr.c b/library/x509_csr.c index eee6e724e..0b4f771f9 100644 --- a/library/x509_csr.c +++ b/library/x509_csr.c @@ -90,18 +90,15 @@ static int x509_csr_get_version( unsigned char **p, } /* - * Parse a CSR + * Parse a CSR in DER format */ -int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) +int x509_csr_parse_der( x509_csr *csr, + const unsigned char *buf, size_t buflen ) { int ret; size_t len; unsigned char *p, *end; x509_buf sig_params; -#if defined(POLARSSL_PEM_PARSE_C) - size_t use_len; - pem_context pem; -#endif memset( &sig_params, 0, sizeof( x509_buf ) ); @@ -113,41 +110,15 @@ int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) x509_csr_init( csr ); -#if defined(POLARSSL_PEM_PARSE_C) - pem_init( &pem ); - ret = pem_read_buffer( &pem, - "-----BEGIN CERTIFICATE REQUEST-----", - "-----END CERTIFICATE REQUEST-----", - buf, NULL, 0, &use_len ); + /* + * first copy the raw DER data + */ + p = (unsigned char *) polarssl_malloc( len = buflen ); - if( ret == 0 ) - { - /* - * Was PEM encoded, steal PEM buffer - */ - p = pem.buf; - pem.buf = NULL; - len = pem.buflen; - pem_free( &pem ); - } - else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - pem_free( &pem ); - return( ret ); - } - else -#endif /* POLARSSL_PEM_PARSE_C */ - { - /* - * nope, copy the raw DER data - */ - p = (unsigned char *) polarssl_malloc( len = buflen ); + if( p == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); - if( p == NULL ) - return( POLARSSL_ERR_X509_MALLOC_FAILED ); - - memcpy( p, buf, buflen ); - } + memcpy( p, buf, buflen ); csr->raw.p = p; csr->raw.len = len; @@ -284,6 +255,51 @@ int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) return( 0 ); } +/* + * Parse a CSR, allowing for PEM or raw DER encoding + */ +int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) +{ + int ret; +#if defined(POLARSSL_PEM_PARSE_C) + size_t use_len; + pem_context pem; +#endif + + /* + * Check for valid input + */ + if( csr == NULL || buf == NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + +#if defined(POLARSSL_PEM_PARSE_C) + pem_init( &pem ); + ret = pem_read_buffer( &pem, + "-----BEGIN CERTIFICATE REQUEST-----", + "-----END CERTIFICATE REQUEST-----", + buf, NULL, 0, &use_len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded, parse the result + */ + if( ( ret = x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 ) + return( ret ); + + pem_free( &pem ); + return( 0 ); + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + pem_free( &pem ); + return( ret ); + } + else +#endif /* POLARSSL_PEM_PARSE_C */ + return( x509_csr_parse_der( csr, buf, buflen ) ); +} + #if defined(POLARSSL_FS_IO) /* * Load a CSR into the structure diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index 8f496b053..9fd3adc3f 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -280,7 +280,7 @@ void x509_csr_parse( char *csr_der_hex, char *ref_out, int ref_ret ) memset( my_out, 0, sizeof( my_out ) ); csr_der = unhexify_alloc( csr_der_hex, &csr_der_len ); - my_ret = x509_csr_parse( &csr, csr_der, csr_der_len ); + my_ret = x509_csr_parse_der( &csr, csr_der, csr_der_len ); TEST_ASSERT( my_ret == ref_ret ); if( ref_ret == 0 )