Split x509_crl_parse_der() out of x509_crl_parse()
diff --git a/ChangeLog b/ChangeLog
index 893c7c1..d1a87be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,7 @@
Features
* Add function pk_check_pair() to test if public and private keys match.
+ * Add x509_crl_parse_der().
Bugfix
* User set CFLAGS were ignore by Cmake with gcc (introduced in 1.3.9, found
diff --git a/include/polarssl/x509_crl.h b/include/polarssl/x509_crl.h
index 9f597a8..4ddbafc 100644
--- a/include/polarssl/x509_crl.h
+++ b/include/polarssl/x509_crl.h
@@ -100,11 +100,23 @@
x509_crl;
/**
- * \brief Parse one or more CRLs and add them
- * to the chained list
+ * \brief Parse a DER-encoded CRL and append it to the chained list
*
* \param chain points to the start of the chain
- * \param buf buffer holding the CRL data
+ * \param buf buffer holding the CRL data in DER format
+ * \param buflen size of the buffer
+ *
+ * \return 0 if successful, or a specific X509 or PEM error code
+ */
+int x509_crl_parse_der( x509_crl *chain,
+ const unsigned char *buf, size_t buflen );
+/**
+ * \brief Parse one or more CRLs and append them to the chained list
+ *
+ * \note Mutliple CRLs are accepted only if using PEM format
+ *
+ * \param chain points to the start of the chain
+ * \param buf buffer holding the CRL data in PEM or DER format
* \param buflen size of the buffer
*
* \return 0 if successful, or a specific X509 or PEM error code
@@ -113,11 +125,12 @@
#if defined(POLARSSL_FS_IO)
/**
- * \brief Load one or more CRLs and add them
- * to the chained list
+ * \brief Load one or more CRLs and append them to the chained list
+ *
+ * \note Mutliple CRLs are accepted only if using PEM format
*
* \param chain points to the start of the chain
- * \param path filename to read the CRLs from
+ * \param path filename to read the CRLs from (in PEM or DER encoding)
*
* \return 0 if successful, or a specific X509 or PEM error code
*/
diff --git a/library/x509_crl.c b/library/x509_crl.c
index b9a5c13..6ad9d00 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -252,25 +252,16 @@
}
/*
- * Parse one or more CRLs and add them to the chained list
+ * Parse one CRLs in DER format and append it to the chained list
*/
-int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
+int x509_crl_parse_der( x509_crl *chain,
+ const unsigned char *buf, size_t buflen )
{
int ret;
size_t len;
unsigned char *p, *end;
- x509_crl *crl;
x509_buf sig_params1, sig_params2;
-
-#if defined(POLARSSL_PEM_PARSE_C)
- size_t use_len;
- pem_context pem;
-#endif
-
- memset( &sig_params1, 0, sizeof( x509_buf ) );
- memset( &sig_params2, 0, sizeof( x509_buf ) );
-
- crl = chain;
+ x509_crl *crl = chain;
/*
* Check for valid input
@@ -278,12 +269,15 @@
if( crl == NULL || buf == NULL )
return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
- while( crl->version != 0 && crl->next != NULL )
- crl = crl->next;
+ memset( &sig_params1, 0, sizeof( x509_buf ) );
+ memset( &sig_params2, 0, sizeof( x509_buf ) );
/*
* Add new CRL on the end of the chain if needed.
*/
+ while( crl->version != 0 && crl->next != NULL )
+ crl = crl->next;
+
if( crl->version != 0 && crl->next == NULL )
{
crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
@@ -298,53 +292,18 @@
crl = crl->next;
}
-#if defined(POLARSSL_PEM_PARSE_C)
- pem_init( &pem );
- ret = pem_read_buffer( &pem,
- "-----BEGIN X509 CRL-----",
- "-----END X509 CRL-----",
- buf, NULL, 0, &use_len );
+ /*
+ * Copy raw DER-encoded CRL
+ */
+ if( ( p = polarssl_malloc( buflen ) ) == NULL )
+ return( POLARSSL_ERR_X509_MALLOC_FAILED );
- if( ret == 0 )
- {
- /*
- * Was PEM encoded
- */
- buflen -= use_len;
- buf += use_len;
-
- /*
- * 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 );
-
- memcpy( p, buf, buflen );
-
- buflen = 0;
- }
+ memcpy( p, buf, buflen );
crl->raw.p = p;
- crl->raw.len = len;
- end = p + len;
+ crl->raw.len = buflen;
+
+ end = p + buflen;
/*
* CertificateList ::= SEQUENCE {
@@ -522,21 +481,58 @@
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
}
- if( buflen > 0 )
+ return( 0 );
+}
+
+/*
+ * Parse one or more CRLs and add them to the chained list
+ */
+int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
+{
+ int ret;
+
+ if( chain == NULL || buf == NULL )
+ return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
+
+#if defined(POLARSSL_PEM_PARSE_C)
+ size_t use_len;
+ pem_context pem;
+
+ pem_init( &pem );
+ ret = pem_read_buffer( &pem,
+ "-----BEGIN X509 CRL-----",
+ "-----END X509 CRL-----",
+ buf, NULL, 0, &use_len );
+
+ if( ret == 0 )
{
- crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
+ /*
+ * Was PEM encoded
+ */
+ buflen -= use_len;
+ buf += use_len;
- if( crl->next == NULL )
- {
- x509_crl_free( crl );
- return( POLARSSL_ERR_X509_MALLOC_FAILED );
- }
+ if( ( ret = x509_crl_parse_der( chain, pem.buf, pem.buflen ) ) != 0 )
+ return( ret );
- x509_crl_init( crl->next );
- crl = crl->next;
-
- return( x509_crl_parse( crl, buf, 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 */
+ {
+ if( ( ret = x509_crl_parse_der( chain, buf, buflen ) ) != 0 )
+ return( ret );
+
+ buflen = 0;
+ }
+
+ if( buflen > 0 )
+ return( x509_crl_parse( chain, buf, buflen ) );
return( 0 );
}