From 77e23fb0e02f7c04177fa1fefdfc7bcbb5cdbed8 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Sun, 15 Sep 2013 20:03:26 +0200 Subject: [PATCH] Move *_pemify() function to PEM module --- include/polarssl/pem.h | 22 +++++++- include/polarssl/pk.h | 4 +- include/polarssl/x509write.h | 4 +- library/pem.c | 50 +++++++++++++++++ library/pkwrite.c | 63 +++++----------------- library/x509write.c | 55 ++++--------------- tests/data_files/server1.crt | 57 -------------------- tests/suites/test_suite_x509write.function | 41 ++++++-------- 8 files changed, 111 insertions(+), 185 deletions(-) diff --git a/include/polarssl/pem.h b/include/polarssl/pem.h index cc6cba14e3..46d89b0222 100644 --- a/include/polarssl/pem.h +++ b/include/polarssl/pem.h @@ -88,13 +88,33 @@ void pem_init( pem_context *ctx ); * the decrypted text starts with an ASN.1 sequence of * appropriate length * - * \return 0 on success, ior a specific PEM error code + * \return 0 on success, or a specific PEM error code */ int pem_read_buffer( pem_context *ctx, const char *header, const char *footer, const unsigned char *data, const unsigned char *pwd, size_t pwdlen, size_t *use_len ); +/** + * \brief Write a buffer of PEM information from a DER encoded + * buffer. + * + * \param header header string to write + * \param footer footer string to write + * \param der_data DER data to write + * \param der_len length of the DER data + * \param buf buffer to write to + * \param buf_len length of output buffer + * \param olen total length written / required (if buf_len is not enough) + * + * \return 0 on success, or a specific PEM or BASE64 error code. On + * POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL olen is the required + * size. + */ +int pem_write_buffer( const char *header, const char *footer, + const unsigned char *der_data, size_t der_len, + unsigned char *buf, size_t buf_len, size_t *olen ); + /** * \brief PEM context memory freeing * diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h index e1fdf89033..58b6b7c1c5 100644 --- a/include/polarssl/pk.h +++ b/include/polarssl/pk.h @@ -477,7 +477,7 @@ int pk_write_key_der( pk_context *pk, unsigned char *buf, size_t size ); */ int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size ); -#if defined(POLARSSL_BASE64_C) +#if defined(POLARSSL_PEM_C) /** * \brief Write a public key to a PEM string * @@ -499,7 +499,7 @@ int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size ); * \return 0 successful, or a specific error code */ int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size ); -#endif /* POLARSSL_BASE64_C */ +#endif /* POLARSSL_PEM_C */ #endif /* POLARSSL_PK_WRITE_C */ /* diff --git a/include/polarssl/x509write.h b/include/polarssl/x509write.h index d41e7086ec..e90b582b32 100644 --- a/include/polarssl/x509write.h +++ b/include/polarssl/x509write.h @@ -414,7 +414,7 @@ int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); -#if defined(POLARSSL_BASE64_C) +#if defined(POLARSSL_PEM_C) /** * \brief Write a built up certificate to a X509 PEM string * @@ -455,7 +455,7 @@ int x509write_crt_pem( x509write_cert *ctx, unsigned char *buf, size_t size, int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); -#endif /* POLARSSL_BASE64_C */ +#endif /* POLARSSL_PEM_C */ #ifdef __cplusplus } diff --git a/library/pem.c b/library/pem.c index 8a6de3a95d..ff7f32cebe 100644 --- a/library/pem.c +++ b/library/pem.c @@ -363,6 +363,56 @@ int pem_read_buffer( pem_context *ctx, const char *header, const char *footer, return( 0 ); } +int pem_write_buffer( const char *header, const char *footer, + const unsigned char *der_data, size_t der_len, + unsigned char *buf, size_t buf_len, size_t *olen ) +{ + int ret; + unsigned char *encode_buf, *c, *p = buf; + size_t len = 0, use_len = 0; + size_t add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1; + + base64_encode( NULL, &use_len, der_data, der_len ); + if( use_len + add_len > buf_len ) + { + *olen = use_len + add_len; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + if( ( encode_buf = polarssl_malloc( use_len ) ) == NULL ) + return( POLARSSL_ERR_PEM_MALLOC_FAILED ); + + if( ( ret = base64_encode( encode_buf, &use_len, der_data, + der_len ) ) != 0 ) + { + polarssl_free( encode_buf ); + return( ret ); + } + + memcpy( p, header, strlen( header ) ); + p += strlen( header ); + c = encode_buf; + + while( use_len ) + { + len = ( use_len > 64 ) ? 64 : use_len; + memcpy( p, c, len ); + use_len -= len; + p += len; + c += len; + *p++ = '\n'; + } + + memcpy( p, footer, strlen( footer ) ); + p += strlen( footer ); + + *p++ = '\0'; + *olen = p - buf; + + polarssl_free( encode_buf ); + return( 0 ); +} + void pem_free( pem_context *ctx ) { if( ctx->buf ) diff --git a/library/pkwrite.c b/library/pkwrite.c index 022281d429..44823d7430 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -40,8 +40,8 @@ #if defined(POLARSSL_ECDSA_C) #include "polarssl/ecdsa.h" #endif -#if defined(POLARSSL_BASE64_C) -#include "polarssl/base64.h" +#if defined(POLARSSL_PEM_C) +#include "polarssl/pem.h" #endif #if defined(POLARSSL_MEMORY_C) @@ -276,45 +276,7 @@ int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size ) return( len ); } -#if defined(POLARSSL_BASE64_C) -static int pk_write_pemify( const char *begin_str, const char *end_str, - const unsigned char *der_data, size_t der_len, - unsigned char *buf, size_t size ) -{ - int ret; - unsigned char base_buf[4096]; - unsigned char *c = base_buf, *p = buf; - size_t len = 0, olen = sizeof(base_buf); - - if( ( ret = base64_encode( base_buf, &olen, der_data, der_len ) ) != 0 ) - return( ret ); - - if( olen + strlen( begin_str ) + strlen( end_str ) + - olen / 64 > size ) - { - return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - memcpy( p, begin_str, strlen( begin_str ) ); - p += strlen( begin_str ); - - while( olen ) - { - len = ( olen > 64 ) ? 64 : olen; - memcpy( p, c, len ); - olen -= len; - p += len; - c += len; - *p++ = '\n'; - } - - memcpy( p, end_str, strlen( end_str ) ); - p += strlen( end_str ); - - *p = '\0'; - - return( 0 ); -} +#if defined(POLARSSL_PEM_C) #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" @@ -328,16 +290,17 @@ int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size ) { int ret; unsigned char output_buf[4096]; + size_t olen = 0; if( ( ret = pk_write_pubkey_der( key, output_buf, - sizeof(output_buf) ) ) < 0 ) + sizeof(output_buf) ) ) < 0 ) { return( ret ); } - if( ( ret = pk_write_pemify( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, + if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, output_buf + sizeof(output_buf) - ret, - ret, buf, size ) ) != 0 ) + ret, buf, size, &olen ) ) != 0 ) { return( ret ); } @@ -350,12 +313,10 @@ int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size ) int ret; unsigned char output_buf[4096]; char *begin, *end; + size_t olen = 0; - if( ( ret = pk_write_key_der( key, output_buf, - sizeof(output_buf) ) ) < 0 ) - { + if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) return( ret ); - } #if defined(POLARSSL_RSA_C) if( pk_get_type( key ) == POLARSSL_PK_RSA ) @@ -375,15 +336,15 @@ int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size ) #endif return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); - if( ( ret = pk_write_pemify( begin, end, + if( ( ret = pem_write_buffer( begin, end, output_buf + sizeof(output_buf) - ret, - ret, buf, size ) ) != 0 ) + ret, buf, size, &olen ) ) != 0 ) { return( ret ); } return( 0 ); } -#endif /* POLARSSL_BASE64_C */ +#endif /* POLARSSL_PEM_C */ #endif /* POLARSSL_PK_WRITE_C */ diff --git a/library/x509write.c b/library/x509write.c index 2231206fc8..3a8c89dd13 100644 --- a/library/x509write.c +++ b/library/x509write.c @@ -42,8 +42,8 @@ #include "polarssl/sha1.h" -#if defined(POLARSSL_BASE64_C) -#include "polarssl/base64.h" +#if defined(POLARSSL_PEM_C) +#include "polarssl/pem.h" #endif #if defined(POLARSSL_MEMORY_C) @@ -816,52 +816,14 @@ int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size, #define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" #define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" -#if defined(POLARSSL_BASE64_C) -static int x509write_pemify( const char *begin_str, const char *end_str, - const unsigned char *der_data, size_t der_len, - unsigned char *buf, size_t size ) -{ - int ret; - unsigned char base_buf[4096]; - unsigned char *c = base_buf, *p = buf; - size_t len = 0, olen = sizeof(base_buf); - - if( ( ret = base64_encode( base_buf, &olen, der_data, der_len ) ) != 0 ) - return( ret ); - - if( olen + strlen( begin_str ) + strlen( end_str ) + - olen / 64 > size ) - { - return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - memcpy( p, begin_str, strlen( begin_str ) ); - p += strlen( begin_str ); - - while( olen ) - { - len = ( olen > 64 ) ? 64 : olen; - memcpy( p, c, len ); - olen -= len; - p += len; - c += len; - *p++ = '\n'; - } - - memcpy( p, end_str, strlen( end_str ) ); - p += strlen( end_str ); - - *p = '\0'; - - return( 0 ); -} - +#if defined(POLARSSL_PEM_C) int x509write_crt_pem( x509write_cert *crt, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; unsigned char output_buf[4096]; + size_t olen = 0; if( ( ret = x509write_crt_der( crt, output_buf, sizeof(output_buf), f_rng, p_rng ) ) < 0 ) @@ -869,9 +831,9 @@ int x509write_crt_pem( x509write_cert *crt, unsigned char *buf, size_t size, return( ret ); } - if( ( ret = x509write_pemify( PEM_BEGIN_CRT, PEM_END_CRT, + if( ( ret = pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, output_buf + sizeof(output_buf) - ret, - ret, buf, size ) ) != 0 ) + ret, buf, size, &olen ) ) != 0 ) { return( ret ); } @@ -885,6 +847,7 @@ int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size, { int ret; unsigned char output_buf[4096]; + size_t olen = 0; if( ( ret = x509write_csr_der( ctx, output_buf, sizeof(output_buf), f_rng, p_rng ) ) < 0 ) @@ -892,9 +855,9 @@ int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size, return( ret ); } - if( ( ret = x509write_pemify( PEM_BEGIN_CSR, PEM_END_CSR, + if( ( ret = pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR, output_buf + sizeof(output_buf) - ret, - ret, buf, size ) ) != 0 ) + ret, buf, size, &olen ) ) != 0 ) { return( ret ); } diff --git a/tests/data_files/server1.crt b/tests/data_files/server1.crt index 7e353cc6e1..d81b26afcf 100644 --- a/tests/data_files/server1.crt +++ b/tests/data_files/server1.crt @@ -1,60 +1,3 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 1 (0x1) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA - Validity - Not Before: Feb 12 14:44:06 2011 GMT - Not After : Feb 12 14:44:06 2021 GMT - Subject: C=NL, O=PolarSSL, CN=PolarSSL Server 1 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public Key: (2048 bit) - Modulus (2048 bit): - 00:a9:02:1f:3d:40:6a:d5:55:53:8b:fd:36:ee:82: - 65:2e:15:61:5e:89:bf:b8:e8:45:90:db:ee:88:16: - 52:d3:f1:43:50:47:96:12:59:64:87:6b:fd:2b:e0: - 46:f9:73:be:dd:cf:92:e1:91:5b:ed:66:a0:6f:89: - 29:79:45:80:d0:83:6a:d5:41:43:77:5f:39:7c:09: - 04:47:82:b0:57:39:70:ed:a3:ec:15:19:1e:a8:33: - 08:47:c1:05:42:a9:fd:4c:c3:b4:df:dd:06:1f:4d: - 10:51:40:67:73:13:0f:40:f8:6d:81:25:5f:0a:b1: - 53:c6:30:7e:15:39:ac:f9:5a:ee:7f:92:9e:a6:05: - 5b:e7:13:97:85:b5:23:92:d9:d4:24:06:d5:09:25: - 89:75:07:dd:a6:1a:8f:3f:09:19:be:ad:65:2c:64: - eb:95:9b:dc:fe:41:5e:17:a6:da:6c:5b:69:cc:02: - ba:14:2c:16:24:9c:4a:dc:cd:d0:f7:52:67:73:f1: - 2d:a0:23:fd:7e:f4:31:ca:2d:70:ca:89:0b:04:db: - 2e:a6:4f:70:6e:9e:ce:bd:58:89:e2:53:59:9e:6e: - 5a:92:65:e2:88:3f:0c:94:19:a3:dd:e5:e8:9d:95: - 13:ed:29:db:ab:70:12:dc:5a:ca:6b:17:ab:52:82: - 54:b1 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - X509v3 Subject Key Identifier: - 1F:74:D6:3F:29:C1:74:74:45:3B:05:12:2C:3D:A8:BD:43:59:02:A6 - X509v3 Authority Key Identifier: - keyid:B4:5A:E4:A5:B3:DE:D2:52:F6:B9:D5:A6:95:0F:EB:3E:BC:C7:FD:FF - - Signature Algorithm: sha1WithRSAEncryption - bd:cf:96:c1:95:1e:9a:c2:6e:d8:88:88:d8:2a:7a:96:20:3e: - 50:0b:c8:c7:df:1d:41:ed:e4:66:cd:b3:02:81:7d:57:04:1b: - 5d:c6:33:59:0f:c1:20:b9:23:34:89:8a:6c:f2:fd:c7:48:36: - 8c:80:e7:e1:9b:c6:60:5c:b0:33:02:0e:fd:df:be:61:bc:18: - 89:0c:38:db:fb:fb:46:23:32:f7:8c:c1:3e:7c:de:1e:2f:3a: - 77:2f:f4:8e:93:8e:25:4c:77:21:74:6c:18:b7:72:8d:bf:f5: - 4f:5d:64:95:c1:6a:1a:70:11:88:af:bc:55:8a:25:30:f3:fa: - 69:f2:af:2d:75:fb:2b:89:22:52:9b:05:42:15:29:13:95:5e: - 33:9a:55:d4:c7:22:d8:44:ce:25:ab:b6:70:ee:34:14:9b:c8: - fc:2f:56:ff:04:7e:18:00:2b:31:ac:36:7f:11:bb:ec:4d:e5: - 69:a6:b4:2c:03:a5:7b:13:3a:03:82:8e:6f:97:f9:70:64:cc: - e4:88:7a:b4:41:79:15:5a:b7:ff:db:f3:34:86:0c:6b:51:6a: - cd:a7:01:2d:91:7c:cd:21:d8:2c:48:a6:5c:17:73:8c:1a:0d: - e2:a0:d4:fd:6c:d1:c9:84:41:46:30:08:e3:d9:b3:1d:7e:ab: - 6a:57:aa:9f -----BEGIN CERTIFICATE----- MIIDPzCCAiegAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index 7e1c25d513..6af5555bcb 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -15,13 +15,11 @@ void x509_csr_check( char *key_file, int md_type, char *cert_req_check_file ) { pk_context key; - pem_context pem; x509write_csr req; - unsigned char *c; unsigned char buf[4000]; unsigned char check_buf[4000]; int ret; - size_t olen = sizeof( check_buf ); + size_t olen = 0, pem_len = 0; FILE *f; char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1"; rnd_pseudo_info rnd_info; @@ -36,25 +34,21 @@ void x509_csr_check( char *key_file, int md_type, x509write_csr_set_key( &req, &key ); TEST_ASSERT( x509write_csr_set_subject_name( &req, subject_name ) == 0 ); - ret = x509write_csr_der( &req, buf, sizeof( buf ), + ret = x509write_csr_pem( &req, buf, sizeof(buf), rnd_pseudo_rand, &rnd_info ); - TEST_ASSERT( ret >= 0 ); + TEST_ASSERT( ret == 0 ); - c = buf + sizeof( buf ) - ret; + pem_len = strlen( (char *) buf ); f = fopen( cert_req_check_file, "r" ); TEST_ASSERT( f != NULL ); - fread( check_buf, 1, sizeof( check_buf ), f ); + olen = fread( check_buf, 1, sizeof( check_buf ), f ); fclose( f ); - pem_init( &pem ); - pem_read_buffer( &pem, "-----BEGIN CERTIFICATE REQUEST-----", "-----END CERTIFICATE REQUEST-----", check_buf, NULL, 0, &olen ); - - TEST_ASSERT( pem.buflen == (size_t) ret ); - TEST_ASSERT( memcmp( c, pem.buf, pem.buflen ) == 0 ); + TEST_ASSERT( olen >= pem_len - 1 ); + TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 ); x509write_csr_free( &req ); - pem_free( &pem ); pk_free( &key ); } /* END_CASE */ @@ -67,14 +61,12 @@ void x509_crt_check( char *subject_key_file, char *subject_pwd, int md_type, char *cert_check_file ) { pk_context subject_key, issuer_key; - pem_context pem; x509write_cert crt; - unsigned char *c; unsigned char buf[4000]; unsigned char check_buf[5000]; mpi serial; int ret; - size_t olen = sizeof( check_buf ); + size_t olen = 0, pem_len = 0; FILE *f; rnd_pseudo_info rnd_info; @@ -103,27 +95,24 @@ void x509_crt_check( char *subject_key_file, char *subject_pwd, TEST_ASSERT( x509write_crt_set_subject_key_identifier( &crt ) == 0 ); TEST_ASSERT( x509write_crt_set_authority_key_identifier( &crt ) == 0 ); - ret = x509write_crt_der( &crt, buf, sizeof(buf), + ret = x509write_crt_pem( &crt, buf, sizeof(buf), rnd_pseudo_rand, &rnd_info ); - TEST_ASSERT( ret >= 0 ); + TEST_ASSERT( ret == 0 ); - c = buf + sizeof( buf ) - ret; + pem_len = strlen( (char *) buf ); f = fopen( cert_check_file, "r" ); TEST_ASSERT( f != NULL ); - TEST_ASSERT( fread( check_buf, 1, sizeof(check_buf), f ) < sizeof(check_buf) ); + TEST_ASSERT( ( olen = fread( check_buf, 1, sizeof(check_buf), f ) ) < + sizeof(check_buf) ); fclose( f ); - pem_init( &pem ); - TEST_ASSERT( pem_read_buffer( &pem, "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----", check_buf, NULL, 0, &olen ) >= 0 ); - - TEST_ASSERT( pem.buflen == (size_t) ret ); - TEST_ASSERT( memcmp( c, pem.buf, pem.buflen ) == 0 ); + TEST_ASSERT( olen >= pem_len - 1 ); + TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 ); x509write_crt_free( &crt ); pk_free( &issuer_key ); pk_free( &subject_key ); - pem_free( &pem ); mpi_free( &serial ); } /* END_CASE */