mirror of
				https://github.com/Mbed-TLS/mbedtls.git
				synced 2025-11-03 20:33:16 +03:00 
			
		
		
		
	Merged refactored x509write module into development
This commit is contained in:
		@@ -20,6 +20,8 @@ Features
 | 
				
			|||||||
   * Support for zeros-and-length (ANSI X.923) padding, one-and-zeros
 | 
					   * Support for zeros-and-length (ANSI X.923) padding, one-and-zeros
 | 
				
			||||||
     (ISO/IEC 7816-4) padding and zero padding in the cipher layer
 | 
					     (ISO/IEC 7816-4) padding and zero padding in the cipher layer
 | 
				
			||||||
   * Support for session tickets (RFC 5077)
 | 
					   * Support for session tickets (RFC 5077)
 | 
				
			||||||
 | 
					   * Certificate Request (CSR) generation with extensions (key_usage,
 | 
				
			||||||
 | 
					     ns_cert_type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Changes
 | 
					Changes
 | 
				
			||||||
   * Ability to enable / disable SSL v3 / TLS 1.0 / TLS 1.1 / TLS 1.2
 | 
					   * Ability to enable / disable SSL v3 / TLS 1.0 / TLS 1.1 / TLS 1.2
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,7 +93,10 @@
 | 
				
			|||||||
/** Returns the size of the binary string, without the trailing \\0 */
 | 
					/** Returns the size of the binary string, without the trailing \\0 */
 | 
				
			||||||
#define OID_SIZE(x) (sizeof(x) - 1)
 | 
					#define OID_SIZE(x) (sizeof(x) - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Compares two asn1_buf structures for the same OID */
 | 
					/** Compares two asn1_buf structures for the same OID. Only works for
 | 
				
			||||||
 | 
					 *  'defined' oid_str values (OID_HMAC_SHA1), you cannot use a 'unsigned
 | 
				
			||||||
 | 
					 *  char *oid' here!
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
#define OID_CMP(oid_str, oid_buf)                                   \
 | 
					#define OID_CMP(oid_str, oid_buf)                                   \
 | 
				
			||||||
        ( ( OID_SIZE(oid_str) == (oid_buf)->len ) &&                \
 | 
					        ( ( OID_SIZE(oid_str) == (oid_buf)->len ) &&                \
 | 
				
			||||||
          memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0 )
 | 
					          memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0 )
 | 
				
			||||||
@@ -139,6 +142,17 @@ typedef struct _asn1_sequence
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
asn1_sequence;
 | 
					asn1_sequence;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Container for a sequence or list of 'named' ASN.1 data items
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef struct _asn1_named_data
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    asn1_buf oid;                   /**< The object identifier. */
 | 
				
			||||||
 | 
					    asn1_buf val;                   /**< The named value. */
 | 
				
			||||||
 | 
					    struct _asn1_named_data *next;  /**< The next entry in the sequence. */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					asn1_named_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Get the length of an ASN.1 element.
 | 
					 * Get the length of an ASN.1 element.
 | 
				
			||||||
 * Updates the pointer to immediately behind the length.
 | 
					 * Updates the pointer to immediately behind the length.
 | 
				
			||||||
@@ -286,6 +300,25 @@ int asn1_get_alg_null( unsigned char **p,
 | 
				
			|||||||
                       const unsigned char *end,
 | 
					                       const unsigned char *end,
 | 
				
			||||||
                       asn1_buf *alg );
 | 
					                       asn1_buf *alg );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Find a specific named_data entry in a sequence or list based on the OID.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param list  The list to seek through
 | 
				
			||||||
 | 
					 * \param oid   The OID to look for
 | 
				
			||||||
 | 
					 * \param len   Size of the OID
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return      NULL if not found, or a pointer to the existing entry.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					asn1_named_data *asn1_find_named_data( asn1_named_data *list,
 | 
				
			||||||
 | 
					                                       const char *oid, size_t len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Free a asn1_named_data entry
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param entry The named data entry to free
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void asn1_free_named_data( asn1_named_data *entry );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,20 +35,164 @@
 | 
				
			|||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a length field in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param len       the length to write
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int asn1_write_len( unsigned char **p, unsigned char *start, size_t len );
 | 
					int asn1_write_len( unsigned char **p, unsigned char *start, size_t len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a ASN.1 tag in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param tag       the tag to write
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag );
 | 
					int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write raw buffer data
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param buf       data buffer to write
 | 
				
			||||||
 | 
					 * \param size      length of the data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
 | 
				
			||||||
 | 
					                           const unsigned char *buf, size_t size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(POLARSSL_BIGNUM_C)
 | 
					#if defined(POLARSSL_BIGNUM_C)
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a big number (ASN1_INTEGER) in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param X         the MPI to write
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X );
 | 
					int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X );
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a NULL tag (ASN1_NULL) with zero data in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int asn1_write_null( unsigned char **p, unsigned char *start );
 | 
					int asn1_write_null( unsigned char **p, unsigned char *start );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write an OID tag (ASN1_OID) and data in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param oid       the OID to write
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int asn1_write_oid( unsigned char **p, unsigned char *start, const char *oid );
 | 
					int asn1_write_oid( unsigned char **p, unsigned char *start, const char *oid );
 | 
				
			||||||
int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, const char *algorithm_oid );
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write an AlgorithmIdentifier sequence in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *                  Note: Uses NULL as algorithm parameter
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param oid       the OID of the algorithm
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
 | 
				
			||||||
 | 
					                                     const char *oid );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write an int tag (ASN1_INTEGER) and value in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param val       the integer value
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int asn1_write_int( unsigned char **p, unsigned char *start, int val );
 | 
					int asn1_write_int( unsigned char **p, unsigned char *start, int val );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a printable string tag (ASN1_PRINTABLE_STRING) and
 | 
				
			||||||
 | 
					 *                  value in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param text      the text to write
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int asn1_write_printable_string( unsigned char **p, unsigned char *start,
 | 
					int asn1_write_printable_string( unsigned char **p, unsigned char *start,
 | 
				
			||||||
                                 char *text );
 | 
					                                 char *text );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write an IA5 string tag (ASN1_IA5_STRING) and
 | 
				
			||||||
 | 
					 *                  value in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param text      the text to write
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
 | 
					int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
 | 
				
			||||||
                                 char *text );
 | 
					                                 char *text );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a bitstring tag (ASN1_BIT_STRING) and
 | 
				
			||||||
 | 
					 *                  value in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param buf       the bitstring
 | 
				
			||||||
 | 
					 * \param bits      the total number of bits in the bitstring
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_write_bitstring( unsigned char **p, unsigned char *start,
 | 
				
			||||||
 | 
					                          const unsigned char *buf, size_t bits );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write an octet string tag (ASN1_OCTET_STRING) and
 | 
				
			||||||
 | 
					 *                  value in ASN.1 format
 | 
				
			||||||
 | 
					 *                  Note: function works backwards in data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param p         reference to current position pointer
 | 
				
			||||||
 | 
					 * \param start     start of the buffer (for bounds-checking)
 | 
				
			||||||
 | 
					 * \param buf       data buffer to write
 | 
				
			||||||
 | 
					 * \param size      length of the data buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          the length written or a negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int asn1_write_octet_string( unsigned char **p, unsigned char *start,
 | 
				
			||||||
 | 
					                             const unsigned char *buf, size_t size );
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,19 +73,20 @@
 | 
				
			|||||||
 * PBKDF2    1  0x007C-0x007C
 | 
					 * PBKDF2    1  0x007C-0x007C
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * High-level module nr (3 bits - 0x1...-0x8...)
 | 
					 * High-level module nr (3 bits - 0x1...-0x8...)
 | 
				
			||||||
 * Name     ID  Nr of Errors
 | 
					 * Name      ID  Nr of Errors
 | 
				
			||||||
 * PEM      1   9
 | 
					 * PEM       1   9
 | 
				
			||||||
 * PKCS#12  1   4 (Started from top)
 | 
					 * PKCS#12   1   4 (Started from top)
 | 
				
			||||||
 * X509     2   25
 | 
					 * X509      2   25
 | 
				
			||||||
 * PK       2   3 (Started from top)
 | 
					 * PK        2   3 (Started from top)
 | 
				
			||||||
 * DHM      3   6
 | 
					 * DHM       3   6
 | 
				
			||||||
 * PKCS5    3   4 (Started from top)
 | 
					 * PKCS5     3   4 (Started from top)
 | 
				
			||||||
 * RSA      4   9
 | 
					 * RSA       4   9
 | 
				
			||||||
 * ECP      4   4 (Started from top)
 | 
					 * ECP       4   4 (Started from top)
 | 
				
			||||||
 * MD       5   4
 | 
					 * MD        5   4
 | 
				
			||||||
 * CIPHER   6   5
 | 
					 * X509WRITE 5   3 (Started from top)
 | 
				
			||||||
 * SSL      6   6 (Started from top)
 | 
					 * CIPHER    6   5
 | 
				
			||||||
 * SSL      7   31
 | 
					 * SSL       6   6 (Started from top)
 | 
				
			||||||
 | 
					 * SSL       7   31
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Module dependent error code (5 bits 0x.08.-0x.F8.)
 | 
					 * Module dependent error code (5 bits 0x.08.-0x.F8.)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -227,6 +227,11 @@
 | 
				
			|||||||
#define OID_PKCS5_PBE_SHA1_DES_CBC      OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
 | 
					#define OID_PKCS5_PBE_SHA1_DES_CBC      OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
 | 
				
			||||||
#define OID_PKCS5_PBE_SHA1_RC2_CBC      OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */
 | 
					#define OID_PKCS5_PBE_SHA1_RC2_CBC      OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * PKCS#8 OIDs
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define OID_PKCS9_CSR_EXT_REQ           OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * PKCS#12 PBE OIDs
 | 
					 * PKCS#12 PBE OIDs
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -169,13 +169,7 @@ typedef asn1_bitstring x509_bitstring;
 | 
				
			|||||||
 * Container for ASN1 named information objects.
 | 
					 * Container for ASN1 named information objects.
 | 
				
			||||||
 * It allows for Relative Distinguished Names (e.g. cn=polarssl,ou=code,etc.).
 | 
					 * It allows for Relative Distinguished Names (e.g. cn=polarssl,ou=code,etc.).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
typedef struct _x509_name
 | 
					typedef asn1_named_data x509_name;
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    x509_buf oid;               /**< The object identifier. */
 | 
					 | 
				
			||||||
    x509_buf val;               /**< The named value. */
 | 
					 | 
				
			||||||
    struct _x509_name *next;    /**< The next named information object. */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
x509_name;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Container for a sequence of ASN.1 items
 | 
					 * Container for a sequence of ASN.1 items
 | 
				
			||||||
@@ -289,42 +283,6 @@ x509_crl;
 | 
				
			|||||||
/** \} name Structures for parsing X.509 certificates and CRLs */
 | 
					/** \} name Structures for parsing X.509 certificates and CRLs */
 | 
				
			||||||
/** \} addtogroup x509_module */
 | 
					/** \} addtogroup x509_module */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * \name Structures for writing X.509 certificates.
 | 
					 | 
				
			||||||
 * XvP: commented out as they are not used.
 | 
					 | 
				
			||||||
 * - <tt>typedef struct _x509_node x509_node;</tt>
 | 
					 | 
				
			||||||
 * - <tt>typedef struct _x509_raw x509_raw;</tt>
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
typedef struct _x509_node
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned char *data;
 | 
					 | 
				
			||||||
    unsigned char *p;
 | 
					 | 
				
			||||||
    unsigned char *end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    size_t len;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
x509_node;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct _x509_raw
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    x509_node raw;
 | 
					 | 
				
			||||||
    x509_node tbs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    x509_node version;
 | 
					 | 
				
			||||||
    x509_node serial;
 | 
					 | 
				
			||||||
    x509_node tbs_signalg;
 | 
					 | 
				
			||||||
    x509_node issuer;
 | 
					 | 
				
			||||||
    x509_node validity;
 | 
					 | 
				
			||||||
    x509_node subject;
 | 
					 | 
				
			||||||
    x509_node subpubkey;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    x509_node signalg;
 | 
					 | 
				
			||||||
    x509_node sign;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
x509_raw;
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \name Functions to read in DHM parameters, a certificate, CRL or private RSA key
 | 
					 * \name Functions to read in DHM parameters, a certificate, CRL or private RSA key
 | 
				
			||||||
 * \{
 | 
					 * \{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,14 +29,40 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(POLARSSL_X509_WRITE_C)
 | 
					#include "x509.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "rsa.h"
 | 
					/**
 | 
				
			||||||
 | 
					 * \addtogroup x509_module
 | 
				
			||||||
 | 
					 * \{
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \name X509 Write Error codes
 | 
				
			||||||
 | 
					 * \{
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define POLARSSL_ERR_X509WRITE_UNKNOWN_OID                -0x5F80  /**< Requested OID is unknown. */
 | 
				
			||||||
 | 
					#define POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA             -0x5F00  /**< Failed to allocate memory. */
 | 
				
			||||||
 | 
					#define POLARSSL_ERR_X509WRITE_MALLOC_FAILED              -0x5E80  /**< Failed to allocate memory. */
 | 
				
			||||||
 | 
					/* \} name */
 | 
				
			||||||
 | 
					/* \} addtogroup x509_module */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \addtogroup x509_module
 | 
				
			||||||
 | 
					 * \{
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \name Structures for writing X.509 CSRs (Certificate Signing Request) 
 | 
				
			||||||
 | 
					 * \{
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Container for CSR named objects
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
typedef struct _x509_req_name
 | 
					typedef struct _x509_req_name
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char oid[128];
 | 
					    char oid[128];
 | 
				
			||||||
@@ -46,15 +72,187 @@ typedef struct _x509_req_name
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
x509_req_name;
 | 
					x509_req_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa );
 | 
					/**
 | 
				
			||||||
int x509_write_key_der( unsigned char *buf, size_t size, rsa_context *rsa );
 | 
					 * Container for a CSR
 | 
				
			||||||
int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
 | 
					 */
 | 
				
			||||||
                         x509_req_name *req_name, md_type_t md_alg );
 | 
					typedef struct _x509_csr
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    rsa_context *rsa;
 | 
				
			||||||
 | 
					    x509_req_name *subject;
 | 
				
			||||||
 | 
					    md_type_t md_alg;
 | 
				
			||||||
 | 
					    asn1_named_data *extensions;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					x509_csr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* \} addtogroup x509_module */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Initialize a CSR context
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx       CSR context to initialize
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void x509write_csr_init( x509_csr *ctx );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Set the subject name for a CSR
 | 
				
			||||||
 | 
					 *                  Subject names should contain a comma-separated list
 | 
				
			||||||
 | 
					 *                  of OID types and values:
 | 
				
			||||||
 | 
					 *                  e.g. "C=NL,O=Offspark,CN=PolarSSL Server 1"
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx           CSR context to use
 | 
				
			||||||
 | 
					 * \param subject_name  subject name to set
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          0 if subject name was parsed successfully, or
 | 
				
			||||||
 | 
					 *                  a specific error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_csr_set_subject_name( x509_csr *ctx, char *subject_name );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Set the RSA key for a CSR (public key will be included,
 | 
				
			||||||
 | 
					 *                  private key used to sign the CSR when writing it)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx       CSR context to use
 | 
				
			||||||
 | 
					 * \param rsa       RSA key to include
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void x509write_csr_set_rsa_key( x509_csr *ctx, rsa_context *rsa );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Set the MD algorithm to use for the signature
 | 
				
			||||||
 | 
					 *                  (e.g. POLARSSL_MD_SHA1)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx       CSR context to use
 | 
				
			||||||
 | 
					 * \param md_ald    MD algorithm to use
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void x509write_csr_set_md_alg( x509_csr *ctx, md_type_t md_alg );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Set the Key Usage Extension flags
 | 
				
			||||||
 | 
					 *                  (e.g. KU_DIGITAL_SIGNATURE | KU_KEY_CERT_SIGN)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx       CSR context to use
 | 
				
			||||||
 | 
					 * \param key_usage key usage flags to set
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          0 if successful, or POLARSSL_ERR_X509WRITE_MALLOC_FAILED
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Set the Netscape Cert Type flags
 | 
				
			||||||
 | 
					 *                  (e.g. NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_EMAIL)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx           CSR context to use
 | 
				
			||||||
 | 
					 * \param ns_cert_type  Netscape Cert Type flags to set
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          0 if successful, or POLARSSL_ERR_X509WRITE_MALLOC_FAILED
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_csr_set_ns_cert_type( x509_csr *ctx, unsigned char ns_cert_type );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Generic function to add to or replace an extension in the CSR
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx       CSR context to use
 | 
				
			||||||
 | 
					 * \param oid       OID of the extension
 | 
				
			||||||
 | 
					 * \param oid_len   length of the OID
 | 
				
			||||||
 | 
					 * \param val       value of the extension OCTET STRING
 | 
				
			||||||
 | 
					 * \param val_len   length of the value data
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          0 if successful, or a POLARSSL_ERR_X509WRITE_MALLOC_FAILED
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_csr_set_extension( x509_csr *ctx,
 | 
				
			||||||
 | 
					                                 const char *oid, size_t oid_len,
 | 
				
			||||||
 | 
					                                 const unsigned char *val, size_t val_len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Free the contents of a CSR context
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx       CSR context to free
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void x509write_csr_free( x509_csr *ctx );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a RSA public key to a PKCS#1 DER structure
 | 
				
			||||||
 | 
					 *                  Note: data is written at the end of the buffer! Use the
 | 
				
			||||||
 | 
					 *                        return value to determine where you should start
 | 
				
			||||||
 | 
					 *                        using the buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param rsa       RSA to write away
 | 
				
			||||||
 | 
					 * \param buf       buffer to write to
 | 
				
			||||||
 | 
					 * \param size      size of the buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          length of data written if successful, or a specific
 | 
				
			||||||
 | 
					 *                  error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_pubkey_der( rsa_context *rsa, unsigned char *buf, size_t size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a RSA key to a PKCS#1 DER structure
 | 
				
			||||||
 | 
					 *                  Note: data is written at the end of the buffer! Use the
 | 
				
			||||||
 | 
					 *                        return value to determine where you should start
 | 
				
			||||||
 | 
					 *                        using the buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param rsa       RSA to write away
 | 
				
			||||||
 | 
					 * \param buf       buffer to write to
 | 
				
			||||||
 | 
					 * \param size      size of the buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          length of data written if successful, or a specific
 | 
				
			||||||
 | 
					 *                  error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_key_der( rsa_context *rsa, unsigned char *buf, size_t size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a CSR (Certificate Signing Request) to a
 | 
				
			||||||
 | 
					 *                  DER structure
 | 
				
			||||||
 | 
					 *                  Note: data is written at the end of the buffer! Use the
 | 
				
			||||||
 | 
					 *                        return value to determine where you should start
 | 
				
			||||||
 | 
					 *                        using the buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param rsa       CSR to write away
 | 
				
			||||||
 | 
					 * \param buf       buffer to write to
 | 
				
			||||||
 | 
					 * \param size      size of the buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          length of data written if successful, or a specific
 | 
				
			||||||
 | 
					 *                  error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_csr_der( x509_csr *ctx, unsigned char *buf, size_t size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(POLARSSL_BASE64_C)
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a RSA public key to a PKCS#1 PEM string
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param rsa       RSA to write away
 | 
				
			||||||
 | 
					 * \param buf       buffer to write to
 | 
				
			||||||
 | 
					 * \param size      size of the buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          0 successful, or a specific error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_pubkey_pem( rsa_context *rsa, unsigned char *buf, size_t size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a RSA key to a PKCS#1 PEM string
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param rsa       RSA to write away
 | 
				
			||||||
 | 
					 * \param buf       buffer to write to
 | 
				
			||||||
 | 
					 * \param size      size of the buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          0 successful, or a specific error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_key_pem( rsa_context *rsa, unsigned char *buf, size_t size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief           Write a CSR (Certificate Signing Request) to a
 | 
				
			||||||
 | 
					 *                  PEM string
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param rsa       CSR to write away
 | 
				
			||||||
 | 
					 * \param buf       buffer to write to
 | 
				
			||||||
 | 
					 * \param size      size of the buffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return          0 successful, or a specific error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int x509write_csr_pem( x509_csr *ctx, unsigned char *buf, size_t size );
 | 
				
			||||||
 | 
					#endif /* POLARSSL_BASE64_C */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* POLARSSL_X509_WRITE_C */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* POLARSSL_X509_WRITE_H */
 | 
					#endif /* POLARSSL_X509_WRITE_H */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -343,4 +343,32 @@ int asn1_get_alg_null( unsigned char **p,
 | 
				
			|||||||
    return( 0 );
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void asn1_free_named_data( asn1_named_data *cur )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if( cur == NULL )
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    polarssl_free( cur->oid.p );
 | 
				
			||||||
 | 
					    polarssl_free( cur->val.p );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset( cur, 0, sizeof( asn1_named_data ) );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					asn1_named_data *asn1_find_named_data( asn1_named_data *list,
 | 
				
			||||||
 | 
					                                       const char *oid, size_t len )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    while( list != NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if( list->oid.len == len &&
 | 
				
			||||||
 | 
					            memcmp( list->oid.p, oid, len ) == 0 )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        list = list->next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( list );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,6 +72,21 @@ int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
 | 
				
			|||||||
    return( 1 );
 | 
					    return( 1 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
 | 
				
			||||||
 | 
					                           const unsigned char *buf, size_t size )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    size_t len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( *p - start < (int) size )
 | 
				
			||||||
 | 
					        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    len = size;
 | 
				
			||||||
 | 
					    (*p) -= len;
 | 
				
			||||||
 | 
					    memcpy( *p, buf, len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( len );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(POLARSSL_BIGNUM_C)
 | 
					#if defined(POLARSSL_BIGNUM_C)
 | 
				
			||||||
int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X )
 | 
					int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -125,15 +140,8 @@ int asn1_write_oid( unsigned char **p, unsigned char *start, const char *oid )
 | 
				
			|||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    size_t len = 0;
 | 
					    size_t len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Write OID
 | 
					    ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
 | 
				
			||||||
    //
 | 
					                  (const unsigned char *) oid, strlen( oid ) ) );
 | 
				
			||||||
    len = strlen( oid );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if( *p - start < (int) len )
 | 
					 | 
				
			||||||
        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (*p) -= len;
 | 
					 | 
				
			||||||
    memcpy( *p, oid, len );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
 | 
					    ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
 | 
				
			||||||
    ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
 | 
					    ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
 | 
				
			||||||
@@ -142,7 +150,7 @@ int asn1_write_oid( unsigned char **p, unsigned char *start, const char *oid )
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
 | 
					int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
 | 
				
			||||||
                                     const char *algorithm_oid )
 | 
					                                     const char *oid )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    size_t null_len = 0;
 | 
					    size_t null_len = 0;
 | 
				
			||||||
@@ -155,7 +163,7 @@ int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Write OID
 | 
					    // Write OID
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, algorithm_oid ) );
 | 
					    ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, oid ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    len = oid_len + null_len;
 | 
					    len = oid_len + null_len;
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + null_len ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + null_len ) );
 | 
				
			||||||
@@ -201,15 +209,8 @@ int asn1_write_printable_string( unsigned char **p, unsigned char *start,
 | 
				
			|||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    size_t len = 0;
 | 
					    size_t len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Write string
 | 
					    ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
 | 
				
			||||||
    //
 | 
					                  (const unsigned char *) text, strlen( text ) ) );
 | 
				
			||||||
    len = strlen( text );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if( *p - start < (int) len )
 | 
					 | 
				
			||||||
        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (*p) -= len;
 | 
					 | 
				
			||||||
    memcpy( *p, text, len );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) );
 | 
				
			||||||
@@ -218,20 +219,13 @@ int asn1_write_printable_string( unsigned char **p, unsigned char *start,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
 | 
					int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
 | 
				
			||||||
                          char *text )
 | 
					                           char *text )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    size_t len = 0;
 | 
					    size_t len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Write string
 | 
					    ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
 | 
				
			||||||
    //
 | 
					                  (const unsigned char *) text, strlen( text ) ) );
 | 
				
			||||||
    len = strlen( text );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if( *p - start < (int) len )
 | 
					 | 
				
			||||||
        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (*p) -= len;
 | 
					 | 
				
			||||||
    memcpy( *p, text, len );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
 | 
				
			||||||
@@ -239,5 +233,44 @@ int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
 | 
				
			|||||||
    return( len );
 | 
					    return( len );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int asn1_write_bitstring( unsigned char **p, unsigned char *start,
 | 
				
			||||||
 | 
					                          const unsigned char *buf, size_t bits )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    size_t len = 0, size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Calculate byte length
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    if( *p - start < (int) size + 1 )
 | 
				
			||||||
 | 
					        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    len = size + 1;
 | 
				
			||||||
 | 
					    (*p) -= size;
 | 
				
			||||||
 | 
					    memcpy( *p, buf, size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Write unused bits
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    *--(*p) = size * 8 - bits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
 | 
				
			||||||
 | 
					    ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( len );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int asn1_write_octet_string( unsigned char **p, unsigned char *start,
 | 
				
			||||||
 | 
					                             const unsigned char *buf, size_t size )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    size_t len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, buf, size ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
 | 
				
			||||||
 | 
					    ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( len );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -149,6 +149,10 @@
 | 
				
			|||||||
#include "polarssl/x509.h"
 | 
					#include "polarssl/x509.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(POLARSSL_X509_WRITE_C)
 | 
				
			||||||
 | 
					#include "polarssl/x509write.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(POLARSSL_XTEA_C)
 | 
					#if defined(POLARSSL_XTEA_C)
 | 
				
			||||||
#include "polarssl/xtea.h"
 | 
					#include "polarssl/xtea.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -432,6 +436,15 @@ void polarssl_strerror( int ret, char *buf, size_t buflen )
 | 
				
			|||||||
            snprintf( buf, buflen, "X509 - Elliptic curve is unsupported (only NIST curves are supported)" );
 | 
					            snprintf( buf, buflen, "X509 - Elliptic curve is unsupported (only NIST curves are supported)" );
 | 
				
			||||||
#endif /* POLARSSL_X509_PARSE_C */
 | 
					#endif /* POLARSSL_X509_PARSE_C */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(POLARSSL_X509_WRITE_C)
 | 
				
			||||||
 | 
					        if( use_ret == -(POLARSSL_ERR_X509WRITE_UNKNOWN_OID) )
 | 
				
			||||||
 | 
					            snprintf( buf, buflen, "X509WRITE - Requested OID is unknown" );
 | 
				
			||||||
 | 
					        if( use_ret == -(POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA) )
 | 
				
			||||||
 | 
					            snprintf( buf, buflen, "X509WRITE - Failed to allocate memory" );
 | 
				
			||||||
 | 
					        if( use_ret == -(POLARSSL_ERR_X509WRITE_MALLOC_FAILED) )
 | 
				
			||||||
 | 
					            snprintf( buf, buflen, "X509WRITE - Failed to allocate memory" );
 | 
				
			||||||
 | 
					#endif /* POLARSSL_X509_WRITE_C */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if( strlen( buf ) == 0 )
 | 
					        if( strlen( buf ) == 0 )
 | 
				
			||||||
            snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
 | 
					            snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,231 @@
 | 
				
			|||||||
#include "polarssl/md.h"
 | 
					#include "polarssl/md.h"
 | 
				
			||||||
#include "polarssl/oid.h"
 | 
					#include "polarssl/oid.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa )
 | 
					#if defined(POLARSSL_BASE64_C)
 | 
				
			||||||
 | 
					#include "polarssl/base64.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(POLARSSL_MEMORY_C)
 | 
				
			||||||
 | 
					#include "polarssl/memory.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#define polarssl_malloc     malloc
 | 
				
			||||||
 | 
					#define polarssl_free       free
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x509write_csr_init( x509_csr *ctx )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memset( ctx, 0, sizeof(x509_csr) );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x509write_csr_free( x509_csr *ctx )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    x509_req_name *cur;
 | 
				
			||||||
 | 
					    asn1_named_data *cur_ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while( ( cur = ctx->subject ) != NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ctx->subject = cur->next;
 | 
				
			||||||
 | 
					        polarssl_free( cur );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while( ( cur_ext = ctx->extensions ) != NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ctx->extensions = cur_ext->next;
 | 
				
			||||||
 | 
					        asn1_free_named_data( cur_ext );
 | 
				
			||||||
 | 
					        polarssl_free( cur_ext );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset( ctx, 0, sizeof(x509_csr) );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x509write_csr_set_md_alg( x509_csr *ctx, md_type_t md_alg )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ctx->md_alg = md_alg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x509write_csr_set_rsa_key( x509_csr *ctx, rsa_context *rsa )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ctx->rsa = rsa;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int x509write_csr_set_subject_name( x509_csr *ctx, char *subject_name )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = 0;
 | 
				
			||||||
 | 
					    char *s = subject_name, *c = s;
 | 
				
			||||||
 | 
					    char *end = s + strlen( s );
 | 
				
			||||||
 | 
					    char *oid = NULL;
 | 
				
			||||||
 | 
					    int in_tag = 1;
 | 
				
			||||||
 | 
					    x509_req_name *cur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while( ctx->subject )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cur = ctx->subject;
 | 
				
			||||||
 | 
					        ctx->subject = ctx->subject->next;
 | 
				
			||||||
 | 
					        polarssl_free( cur );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while( c <= end )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if( in_tag && *c == '=' )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if( memcmp( s, "CN", 2 ) == 0 && c - s == 2 )
 | 
				
			||||||
 | 
					                oid = OID_AT_CN;
 | 
				
			||||||
 | 
					            else if( memcmp( s, "C", 1 ) == 0 && c - s == 1 )
 | 
				
			||||||
 | 
					                oid = OID_AT_COUNTRY;
 | 
				
			||||||
 | 
					            else if( memcmp( s, "O", 1 ) == 0 && c - s == 1 )
 | 
				
			||||||
 | 
					                oid = OID_AT_ORGANIZATION;
 | 
				
			||||||
 | 
					            else if( memcmp( s, "L", 1 ) == 0 && c - s == 1 )
 | 
				
			||||||
 | 
					                oid = OID_AT_LOCALITY;
 | 
				
			||||||
 | 
					            else if( memcmp( s, "R", 1 ) == 0 && c - s == 1 )
 | 
				
			||||||
 | 
					                oid = OID_PKCS9_EMAIL;
 | 
				
			||||||
 | 
					            else if( memcmp( s, "OU", 2 ) == 0 && c - s == 2 )
 | 
				
			||||||
 | 
					                oid = OID_AT_ORG_UNIT;
 | 
				
			||||||
 | 
					            else if( memcmp( s, "ST", 2 ) == 0 && c - s == 2 )
 | 
				
			||||||
 | 
					                oid = OID_AT_STATE;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ret = POLARSSL_ERR_X509WRITE_UNKNOWN_OID;
 | 
				
			||||||
 | 
					                goto exit;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            s = c + 1;
 | 
				
			||||||
 | 
					            in_tag = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if( !in_tag && ( *c == ',' || c == end ) )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if( c - s > 127 )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ret = POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA;
 | 
				
			||||||
 | 
					                goto exit;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            cur = polarssl_malloc( sizeof(x509_req_name) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if( cur == NULL )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ret = POLARSSL_ERR_X509WRITE_MALLOC_FAILED;
 | 
				
			||||||
 | 
					                goto exit;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            memset( cur, 0, sizeof(x509_req_name) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            cur->next = ctx->subject;
 | 
				
			||||||
 | 
					            ctx->subject = cur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            strncpy( cur->oid, oid, strlen( oid ) );
 | 
				
			||||||
 | 
					            strncpy( cur->name, s, c - s );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            s = c + 1;
 | 
				
			||||||
 | 
					            in_tag = 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        c++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exit:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( ret );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int x509write_csr_set_extension( x509_csr *ctx,
 | 
				
			||||||
 | 
					                                 const char *oid, size_t oid_len,
 | 
				
			||||||
 | 
					                                 const unsigned char *val, size_t val_len )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    asn1_named_data *cur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( cur = asn1_find_named_data( ctx->extensions, oid,
 | 
				
			||||||
 | 
					                                      oid_len ) ) == NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cur = polarssl_malloc( sizeof(asn1_named_data) );
 | 
				
			||||||
 | 
					        if( cur == NULL )
 | 
				
			||||||
 | 
					            return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        memset( cur, 0, sizeof(asn1_named_data) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cur->oid.len = oid_len;
 | 
				
			||||||
 | 
					        cur->oid.p = polarssl_malloc( oid_len );
 | 
				
			||||||
 | 
					        if( cur->oid.p == NULL )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            polarssl_free( cur );
 | 
				
			||||||
 | 
					            return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cur->val.len = val_len;
 | 
				
			||||||
 | 
					        cur->val.p = polarssl_malloc( val_len );
 | 
				
			||||||
 | 
					        if( cur->val.p == NULL )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            polarssl_free( cur->oid.p );
 | 
				
			||||||
 | 
					            polarssl_free( cur );
 | 
				
			||||||
 | 
					            return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        memcpy( cur->oid.p, oid, oid_len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cur->next = ctx->extensions;
 | 
				
			||||||
 | 
					        ctx->extensions = cur;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( cur->val.len != val_len )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        polarssl_free( cur->val.p );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cur->val.len = val_len;
 | 
				
			||||||
 | 
					        cur->val.p = polarssl_malloc( val_len );
 | 
				
			||||||
 | 
					        if( cur->val.p == NULL )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            polarssl_free( cur->oid.p );
 | 
				
			||||||
 | 
					            polarssl_free( cur );
 | 
				
			||||||
 | 
					            return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy( cur->val.p, val, val_len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned char buf[4];
 | 
				
			||||||
 | 
					    unsigned char *c;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    c = buf + 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 )
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = x509write_csr_set_extension( ctx, OID_KEY_USAGE,
 | 
				
			||||||
 | 
					                                       OID_SIZE( OID_KEY_USAGE ),
 | 
				
			||||||
 | 
					                                       buf, 4 );
 | 
				
			||||||
 | 
					    if( ret != 0 )
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int x509write_csr_set_ns_cert_type( x509_csr *ctx, unsigned char ns_cert_type )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned char buf[4];
 | 
				
			||||||
 | 
					    unsigned char *c;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    c = buf + 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 )
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = x509write_csr_set_extension( ctx, OID_NS_CERT_TYPE,
 | 
				
			||||||
 | 
					                                       OID_SIZE( OID_NS_CERT_TYPE ),
 | 
				
			||||||
 | 
					                                       buf, 4 );
 | 
				
			||||||
 | 
					    if( ret != 0 )
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int x509write_pubkey_der( rsa_context *rsa, unsigned char *buf, size_t size )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    unsigned char *c;
 | 
					    unsigned char *c;
 | 
				
			||||||
@@ -41,6 +265,12 @@ int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    c = buf + size - 1;
 | 
					    c = buf + size - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    *  RSAPublicKey ::= SEQUENCE {
 | 
				
			||||||
 | 
					    *      modulus           INTEGER,  -- n
 | 
				
			||||||
 | 
					    *      publicExponent    INTEGER   -- e
 | 
				
			||||||
 | 
					    *  }
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,6 +280,11 @@ int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa )
 | 
				
			|||||||
    if( c - buf < 1 )
 | 
					    if( c - buf < 1 )
 | 
				
			||||||
        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
 | 
					        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
 | 
				
			||||||
 | 
					     *       algorithm            AlgorithmIdentifier,
 | 
				
			||||||
 | 
					     *       subjectPublicKey     BIT STRING }
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    *--c = 0;
 | 
					    *--c = 0;
 | 
				
			||||||
    len += 1;
 | 
					    len += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,7 +299,7 @@ int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa )
 | 
				
			|||||||
    return( len );
 | 
					    return( len );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int x509_write_key_der( unsigned char *buf, size_t size, rsa_context *rsa )
 | 
					int x509write_key_der( rsa_context *rsa, unsigned char *buf, size_t size )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    unsigned char *c;
 | 
					    unsigned char *c;
 | 
				
			||||||
@@ -167,8 +402,7 @@ static int x509_write_sig( unsigned char **p, unsigned char *start,
 | 
				
			|||||||
    return( len );
 | 
					    return( len );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
 | 
					int x509write_csr_der( x509_csr *ctx, unsigned char *buf, size_t size )
 | 
				
			||||||
                         x509_req_name *req_name, md_type_t md_alg )
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    const char *sig_oid;
 | 
					    const char *sig_oid;
 | 
				
			||||||
@@ -178,15 +412,52 @@ int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
 | 
				
			|||||||
    unsigned char tmp_buf[2048];
 | 
					    unsigned char tmp_buf[2048];
 | 
				
			||||||
    size_t sub_len = 0, pub_len = 0, sig_len = 0;
 | 
					    size_t sub_len = 0, pub_len = 0, sig_len = 0;
 | 
				
			||||||
    size_t len = 0;
 | 
					    size_t len = 0;
 | 
				
			||||||
    x509_req_name *cur = req_name;
 | 
					    x509_req_name *cur = ctx->subject;
 | 
				
			||||||
 | 
					    asn1_named_data *cur_ext = ctx->extensions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c = tmp_buf + 2048 - 1;
 | 
					    c = tmp_buf + 2048 - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, 0 ) );
 | 
					    while( cur_ext != NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        size_t ext_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->val.p,
 | 
				
			||||||
 | 
					                                                      cur_ext->val.len ) );
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->val.len ) );
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OCTET_STRING ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->oid.p,
 | 
				
			||||||
 | 
					                                                      cur_ext->oid.len ) );
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->oid.len ) );
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OID ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cur_ext = cur_ext->next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        len += ext_len;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( len )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SET ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
 | 
				
			||||||
 | 
					        ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &rsa->E ) );
 | 
					    ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->E ) );
 | 
				
			||||||
    ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &rsa->N ) );
 | 
					    ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->N ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
 | 
					    ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
 | 
				
			||||||
    ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
 | 
					    ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
 | 
				
			||||||
@@ -194,6 +465,11 @@ int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
 | 
				
			|||||||
    if( c - tmp_buf < 1 )
 | 
					    if( c - tmp_buf < 1 )
 | 
				
			||||||
        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
 | 
					        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     *  AlgorithmIdentifier  ::=  SEQUENCE  {
 | 
				
			||||||
 | 
					     *       algorithm               OBJECT IDENTIFIER,
 | 
				
			||||||
 | 
					     *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    *--c = 0;
 | 
					    *--c = 0;
 | 
				
			||||||
    pub_len += 1;
 | 
					    pub_len += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -217,21 +493,24 @@ int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
 | 
				
			|||||||
    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
 | 
				
			||||||
    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
 | 
					    ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    md( md_info_from_type( md_alg ), c, len, hash );
 | 
					    md( md_info_from_type( ctx->md_alg ), c, len, hash );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rsa_pkcs1_sign( rsa, NULL, NULL, RSA_PRIVATE, md_alg, 0, hash, sig );
 | 
					    rsa_pkcs1_sign( ctx->rsa, NULL, NULL, RSA_PRIVATE, ctx->md_alg, 0, hash, sig );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Generate correct OID
 | 
					    // Generate correct OID
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    ret = oid_get_oid_by_sig_alg( POLARSSL_PK_RSA, md_alg, &sig_oid );
 | 
					    ret = oid_get_oid_by_sig_alg( POLARSSL_PK_RSA, ctx->md_alg, &sig_oid );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c2 = buf + size - 1;
 | 
					    c2 = buf + size - 1;
 | 
				
			||||||
    ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, rsa->len ) );
 | 
					    ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, ctx->rsa->len ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c2 -= len;
 | 
					    c2 -= len;
 | 
				
			||||||
    memcpy( c2, c, len );
 | 
					    memcpy( c2, c, len );
 | 
				
			||||||
@@ -243,4 +522,117 @@ int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
 | 
				
			|||||||
    return( len );
 | 
					    return( len );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PEM_BEGIN_CSR           "-----BEGIN CERTIFICATE REQUEST-----\n"
 | 
				
			||||||
 | 
					#define PEM_END_CSR             "-----END CERTIFICATE REQUEST-----\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PEM_BEGIN_PUBLIC_KEY    "-----BEGIN PUBLIC KEY-----\n"
 | 
				
			||||||
 | 
					#define PEM_END_PUBLIC_KEY      "-----END PUBLIC KEY-----\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PEM_BEGIN_PRIVATE_KEY   "-----BEGIN RSA PRIVATE KEY-----\n"
 | 
				
			||||||
 | 
					#define PEM_END_PRIVATE_KEY     "-----END RSA PRIVATE KEY-----\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 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int x509write_pubkey_pem( rsa_context *rsa, unsigned char *buf, size_t size )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    unsigned char output_buf[4096];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = x509write_pubkey_der( rsa, output_buf,
 | 
				
			||||||
 | 
					                                      sizeof(output_buf) ) ) < 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = x509write_pemify( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
 | 
				
			||||||
 | 
					                                  output_buf + sizeof(output_buf) - 1 - ret,
 | 
				
			||||||
 | 
					                                  ret, buf, size ) ) != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int x509write_key_pem( rsa_context *rsa, unsigned char *buf, size_t size )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    unsigned char output_buf[4096];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = x509write_key_der( rsa, output_buf,
 | 
				
			||||||
 | 
					                                      sizeof(output_buf) ) ) < 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = x509write_pemify( PEM_BEGIN_PRIVATE_KEY, PEM_END_PRIVATE_KEY,
 | 
				
			||||||
 | 
					                                  output_buf + sizeof(output_buf) - 1 - ret,
 | 
				
			||||||
 | 
					                                  ret, buf, size ) ) != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int x509write_csr_pem( x509_csr *ctx, unsigned char *buf, size_t size )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    unsigned char output_buf[4096];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = x509write_csr_der( ctx, output_buf,
 | 
				
			||||||
 | 
					                                      sizeof(output_buf) ) ) < 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = x509write_pemify( PEM_BEGIN_CSR, PEM_END_CSR,
 | 
				
			||||||
 | 
					                                  output_buf + sizeof(output_buf) - 1 - ret,
 | 
				
			||||||
 | 
					                                  ret, buf, size ) ) != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif /* POLARSSL_BASE64_C */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								programs/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								programs/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -35,6 +35,7 @@ test/o_p_test
 | 
				
			|||||||
test/selftest
 | 
					test/selftest
 | 
				
			||||||
test/ssl_cert_test
 | 
					test/ssl_cert_test
 | 
				
			||||||
test/ssl_test
 | 
					test/ssl_test
 | 
				
			||||||
 | 
					util/pem2der
 | 
				
			||||||
util/strerror
 | 
					util/strerror
 | 
				
			||||||
x509/cert_app
 | 
					x509/cert_app
 | 
				
			||||||
x509/cert_req
 | 
					x509/cert_req
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ APPS =	aes/aescrypt2	aes/crypt_and_hash	\
 | 
				
			|||||||
	test/ssl_cert_test	test/benchmark		\
 | 
						test/ssl_cert_test	test/benchmark		\
 | 
				
			||||||
	test/selftest		test/ssl_test		\
 | 
						test/selftest		test/ssl_test		\
 | 
				
			||||||
	test/ecp-bench							\
 | 
						test/ecp-bench							\
 | 
				
			||||||
	util/strerror							\
 | 
						util/pem2der		util/strerror		\
 | 
				
			||||||
	x509/cert_app		x509/crl_app		\
 | 
						x509/cert_app		x509/crl_app		\
 | 
				
			||||||
	x509/cert_req
 | 
						x509/cert_req
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -195,6 +195,10 @@ test/o_p_test: test/o_p_test.c ../library/libpolarssl.a
 | 
				
			|||||||
	echo   "  CC    test/o_p_test.c"
 | 
						echo   "  CC    test/o_p_test.c"
 | 
				
			||||||
	$(CC) $(CFLAGS) $(OFLAGS) test/o_p_test.c    $(LDFLAGS) -o $@ -lssl -lcrypto
 | 
						$(CC) $(CFLAGS) $(OFLAGS) test/o_p_test.c    $(LDFLAGS) -o $@ -lssl -lcrypto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					util/pem2der: util/pem2der.c ../library/libpolarssl.a
 | 
				
			||||||
 | 
						echo   "  CC    util/pem2der.c"
 | 
				
			||||||
 | 
						$(CC) $(CFLAGS) $(OFLAGS) util/pem2der.c    $(LDFLAGS) -o $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
util/strerror: util/strerror.c ../library/libpolarssl.a
 | 
					util/strerror: util/strerror.c ../library/libpolarssl.a
 | 
				
			||||||
	echo   "  CC    util/strerror.c"
 | 
						echo   "  CC    util/strerror.c"
 | 
				
			||||||
	$(CC) $(CFLAGS) $(OFLAGS) util/strerror.c    $(LDFLAGS) -o $@
 | 
						$(CC) $(CFLAGS) $(OFLAGS) util/strerror.c    $(LDFLAGS) -o $@
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *  Key reading application
 | 
					 *  Key writing application
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  Copyright (C) 2006-2013, Brainspark B.V.
 | 
					 *  Copyright (C) 2006-2013, Brainspark B.V.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -60,11 +60,15 @@ int main( int argc, char *argv[] )
 | 
				
			|||||||
#define OUTPUT_MODE_PRIVATE            1
 | 
					#define OUTPUT_MODE_PRIVATE            1
 | 
				
			||||||
#define OUTPUT_MODE_PUBLIC             2
 | 
					#define OUTPUT_MODE_PUBLIC             2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OUTPUT_FORMAT_PEM              0
 | 
				
			||||||
 | 
					#define OUTPUT_FORMAT_DER              1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DFL_MODE                MODE_NONE
 | 
					#define DFL_MODE                MODE_NONE
 | 
				
			||||||
#define DFL_FILENAME            "keyfile.key"
 | 
					#define DFL_FILENAME            "keyfile.key"
 | 
				
			||||||
#define DFL_DEBUG_LEVEL         0
 | 
					#define DFL_DEBUG_LEVEL         0
 | 
				
			||||||
#define DFL_OUTPUT_MODE          OUTPUT_MODE_NONE
 | 
					#define DFL_OUTPUT_MODE         OUTPUT_MODE_NONE
 | 
				
			||||||
#define DFL_OUTPUT_FILENAME     "keyfile.pem"
 | 
					#define DFL_OUTPUT_FILENAME     "keyfile.pem"
 | 
				
			||||||
 | 
					#define DFL_OUTPUT_FORMAT       OUTPUT_FORMAT_PEM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * global options
 | 
					 * global options
 | 
				
			||||||
@@ -75,79 +79,80 @@ struct options
 | 
				
			|||||||
    const char *filename;       /* filename of the key file             */
 | 
					    const char *filename;       /* filename of the key file             */
 | 
				
			||||||
    int output_mode;            /* the output mode to use               */
 | 
					    int output_mode;            /* the output mode to use               */
 | 
				
			||||||
    const char *output_file;    /* where to store the constructed key file  */
 | 
					    const char *output_file;    /* where to store the constructed key file  */
 | 
				
			||||||
 | 
					    int output_format;          /* the output format to use             */
 | 
				
			||||||
} opt;
 | 
					} opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void write_public_key( rsa_context *rsa, const char *output_file )
 | 
					static int write_public_key( rsa_context *rsa, const char *output_file )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
    FILE *f;
 | 
					    FILE *f;
 | 
				
			||||||
    unsigned char output_buf[16000];
 | 
					    unsigned char output_buf[16000];
 | 
				
			||||||
    unsigned char base_buf[16000];
 | 
					    unsigned char *c = output_buf;
 | 
				
			||||||
    unsigned char *c;
 | 
					    size_t len = 0;
 | 
				
			||||||
    int ret;
 | 
					 | 
				
			||||||
    size_t len = 0, olen = 16000;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(output_buf, 0, 16000);
 | 
					    memset(output_buf, 0, 16000);
 | 
				
			||||||
    ret = x509_write_pubkey_der( output_buf, 16000, rsa );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( ret < 0 )
 | 
					    if( opt.output_format == OUTPUT_FORMAT_PEM )
 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    len = ret;
 | 
					 | 
				
			||||||
    c = output_buf + 15999 - len;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    base64_encode( base_buf, &olen, c, len );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    c = base_buf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    f = fopen( output_file, "w" );
 | 
					 | 
				
			||||||
    fprintf(f, "-----BEGIN PUBLIC KEY-----\n");
 | 
					 | 
				
			||||||
    while (olen)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int use_len = olen;
 | 
					        if( ( ret = x509write_pubkey_pem( rsa, output_buf, 16000 ) ) != 0 )
 | 
				
			||||||
        if (use_len > 64) use_len = 64;
 | 
					            return( ret );
 | 
				
			||||||
        fwrite( c, 1, use_len, f );
 | 
					
 | 
				
			||||||
        olen -= use_len;
 | 
					        len = strlen( (char *) output_buf );
 | 
				
			||||||
        c += use_len;
 | 
					 | 
				
			||||||
        fprintf(f, "\n");
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fprintf(f, "-----END PUBLIC KEY-----\n");
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if( ( ret = x509write_pubkey_der( rsa, output_buf, 16000 ) ) < 0 )
 | 
				
			||||||
 | 
					            return( ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        len = ret;
 | 
				
			||||||
 | 
					        c = output_buf + sizeof(output_buf) - len - 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( f = fopen( output_file, "w" ) ) == NULL )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( fwrite( c, 1, len, f ) != len )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fclose(f);
 | 
					    fclose(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void write_private_key( rsa_context *rsa, const char *output_file )
 | 
					static int write_private_key( rsa_context *rsa, const char *output_file )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
    FILE *f;
 | 
					    FILE *f;
 | 
				
			||||||
    unsigned char output_buf[16000];
 | 
					    unsigned char output_buf[16000];
 | 
				
			||||||
    unsigned char base_buf[16000];
 | 
					    unsigned char *c = output_buf;
 | 
				
			||||||
    unsigned char *c;
 | 
					    size_t len = 0;
 | 
				
			||||||
    int ret;
 | 
					 | 
				
			||||||
    size_t len = 0, olen = 16000;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(output_buf, 0, 16000);
 | 
					    memset(output_buf, 0, 16000);
 | 
				
			||||||
    ret = x509_write_key_der( output_buf, 16000, rsa );
 | 
					    if( opt.output_format == OUTPUT_FORMAT_PEM )
 | 
				
			||||||
    if( ret < 0 )
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    len = ret;
 | 
					 | 
				
			||||||
    c = output_buf + 15999 - len;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    base64_encode( base_buf, &olen, c, len );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    c = base_buf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    f = fopen( output_file, "w" );
 | 
					 | 
				
			||||||
    fprintf(f, "-----BEGIN RSA PRIVATE KEY-----\n");
 | 
					 | 
				
			||||||
    while (olen)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int use_len = olen;
 | 
					        if( ( ret = x509write_key_pem( rsa, output_buf, 16000 ) ) != 0 )
 | 
				
			||||||
        if (use_len > 64) use_len = 64;
 | 
					            return( ret );
 | 
				
			||||||
        fwrite( c, 1, use_len, f );
 | 
					
 | 
				
			||||||
        olen -= use_len;
 | 
					        len = strlen( (char *) output_buf );
 | 
				
			||||||
        c += use_len;
 | 
					 | 
				
			||||||
        fprintf(f, "\n");
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fprintf(f, "-----END RSA PRIVATE KEY-----\n");
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if( ( ret = x509write_key_der( rsa, output_buf, 16000 ) ) < 0 )
 | 
				
			||||||
 | 
					            return( ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        len = ret;
 | 
				
			||||||
 | 
					        c = output_buf + sizeof(output_buf) - len - 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( f = fopen( output_file, "w" ) ) == NULL )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( fwrite( c, 1, len, f ) != len )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fclose(f);
 | 
					    fclose(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USAGE \
 | 
					#define USAGE \
 | 
				
			||||||
@@ -156,7 +161,8 @@ static void write_private_key( rsa_context *rsa, const char *output_file )
 | 
				
			|||||||
    "    mode=private|public default: none\n"           \
 | 
					    "    mode=private|public default: none\n"           \
 | 
				
			||||||
    "    filename=%%s         default: keyfile.key\n"   \
 | 
					    "    filename=%%s         default: keyfile.key\n"   \
 | 
				
			||||||
    "    output_mode=private|public default: none\n"    \
 | 
					    "    output_mode=private|public default: none\n"    \
 | 
				
			||||||
    "    output_file=%%s      defeult: keyfile.pem\n"   \
 | 
					    "    output_file=%%s      default: keyfile.pem\n"   \
 | 
				
			||||||
 | 
					    "    output_format=pem|der default: pem\n"          \
 | 
				
			||||||
    "\n"
 | 
					    "\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main( int argc, char *argv[] )
 | 
					int main( int argc, char *argv[] )
 | 
				
			||||||
@@ -184,6 +190,7 @@ int main( int argc, char *argv[] )
 | 
				
			|||||||
    opt.filename            = DFL_FILENAME;
 | 
					    opt.filename            = DFL_FILENAME;
 | 
				
			||||||
    opt.output_mode         = DFL_OUTPUT_MODE;
 | 
					    opt.output_mode         = DFL_OUTPUT_MODE;
 | 
				
			||||||
    opt.output_file         = DFL_OUTPUT_FILENAME;
 | 
					    opt.output_file         = DFL_OUTPUT_FILENAME;
 | 
				
			||||||
 | 
					    opt.output_format       = DFL_OUTPUT_FORMAT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for( i = 1; i < argc; i++ )
 | 
					    for( i = 1; i < argc; i++ )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -210,6 +217,15 @@ int main( int argc, char *argv[] )
 | 
				
			|||||||
            else
 | 
					            else
 | 
				
			||||||
                goto usage;
 | 
					                goto usage;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        else if( strcmp( p, "output_format" ) == 0 )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if( strcmp( q, "pem" ) == 0 )
 | 
				
			||||||
 | 
					                opt.output_format = OUTPUT_FORMAT_PEM;
 | 
				
			||||||
 | 
					            else if( strcmp( q, "der" ) == 0 )
 | 
				
			||||||
 | 
					                opt.output_format = OUTPUT_FORMAT_DER;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                goto usage;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        else if( strcmp( p, "filename" ) == 0 )
 | 
					        else if( strcmp( p, "filename" ) == 0 )
 | 
				
			||||||
            opt.filename = q;
 | 
					            opt.filename = q;
 | 
				
			||||||
        else if( strcmp( p, "output_file" ) == 0 )
 | 
					        else if( strcmp( p, "output_file" ) == 0 )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,9 @@ set(libs
 | 
				
			|||||||
add_executable(strerror strerror.c)
 | 
					add_executable(strerror strerror.c)
 | 
				
			||||||
target_link_libraries(strerror ${libs})
 | 
					target_link_libraries(strerror ${libs})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install(TARGETS strerror
 | 
					add_executable(pem2der pem2der.c)
 | 
				
			||||||
 | 
					target_link_libraries(pem2der ${libs})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install(TARGETS strerror pem2der
 | 
				
			||||||
        DESTINATION "bin"
 | 
					        DESTINATION "bin"
 | 
				
			||||||
        PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
 | 
					        PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										288
									
								
								programs/util/pem2der.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								programs/util/pem2der.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,288 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  Convert PEM to DER
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Copyright (C) 2006-2013, Brainspark B.V.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This file is part of PolarSSL (http://www.polarssl.org)
 | 
				
			||||||
 | 
					 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  All rights reserved.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 *  it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 *  the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 *  (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 *  GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 *  with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _CRT_SECURE_NO_DEPRECATE
 | 
				
			||||||
 | 
					#define _CRT_SECURE_NO_DEPRECATE 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "polarssl/config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "polarssl/error.h"
 | 
				
			||||||
 | 
					#include "polarssl/base64.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DFL_FILENAME            "file.pem"
 | 
				
			||||||
 | 
					#define DFL_OUTPUT_FILENAME     "file.der"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * global options
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct options
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char *filename;             /* filename of the input file             */
 | 
				
			||||||
 | 
					    char *output_file;          /* where to store the output              */
 | 
				
			||||||
 | 
					} opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int convert_pem_to_der( const unsigned char *input, size_t ilen,
 | 
				
			||||||
 | 
					                        unsigned char *output, size_t *olen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    const unsigned char *s1, *s2, *end = input + ilen;
 | 
				
			||||||
 | 
					    size_t len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s1 = (unsigned char *) strstr( (char *) input, "-----BEGIN" );
 | 
				
			||||||
 | 
					    if( s1 == NULL )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s2 = (unsigned char *) strstr( (char *) input, "-----END" );
 | 
				
			||||||
 | 
					    if( s2 == NULL )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s1 += 10;
 | 
				
			||||||
 | 
					    while( s1 < end && *s1 != '-' )
 | 
				
			||||||
 | 
					        s1++;
 | 
				
			||||||
 | 
					    while( s1 < end && *s1 == '-' )
 | 
				
			||||||
 | 
					        s1++;
 | 
				
			||||||
 | 
					    if( *s1 == '\r' ) s1++;
 | 
				
			||||||
 | 
					    if( *s1 == '\n' ) s1++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( s2 <= s1 || s2 > end )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = base64_decode( NULL, &len, (const unsigned char *) s1, s2 - s1 );
 | 
				
			||||||
 | 
					    if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( len > *olen )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = base64_decode( output, &len, (const unsigned char *) s1,
 | 
				
			||||||
 | 
					                               s2 - s1 ) ) != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *olen = len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Load all data from a file into a given buffer.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int load_file( const char *path, unsigned char **buf, size_t *n )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    FILE *f;
 | 
				
			||||||
 | 
					    long size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( f = fopen( path, "rb" ) ) == NULL )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fseek( f, 0, SEEK_END );
 | 
				
			||||||
 | 
					    if( ( size = ftell( f ) ) == -1 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        fclose( f );
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fseek( f, 0, SEEK_SET );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *n = (size_t) size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( *n + 1 == 0 ||
 | 
				
			||||||
 | 
					        ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        fclose( f );
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( fread( *buf, 1, *n, f ) != *n )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        fclose( f );
 | 
				
			||||||
 | 
					        free( *buf );
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fclose( f );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (*buf)[*n] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Write buffer to a file
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int write_file( const char *path, unsigned char *buf, size_t n )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    FILE *f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( f = fopen( path, "wb" ) ) == NULL )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( fwrite( buf, 1, n, f ) != n )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        fclose( f );
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fclose( f );
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define USAGE \
 | 
				
			||||||
 | 
					    "\n usage: pem2der param=<>...\n"                   \
 | 
				
			||||||
 | 
					    "\n acceptable parameters:\n"                       \
 | 
				
			||||||
 | 
					    "    filename=%%s         default: file.pem\n"      \
 | 
				
			||||||
 | 
					    "    output_file=%%s      default: file.der\n"      \
 | 
				
			||||||
 | 
					    "\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(POLARSSL_BASE64_C) || !defined(POLARSSL_FS_IO)
 | 
				
			||||||
 | 
					int main( int argc, char *argv[] )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ((void) argc);
 | 
				
			||||||
 | 
					    ((void) argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("POLARSSL_BASE64_C and/or POLARSSL_FS_IO not defined.\n");
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					int main( int argc, char *argv[] )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = 0;
 | 
				
			||||||
 | 
					    unsigned char *pem_buffer = NULL;
 | 
				
			||||||
 | 
					    unsigned char der_buffer[4096];
 | 
				
			||||||
 | 
					    char buf[1024];
 | 
				
			||||||
 | 
					    size_t pem_size, der_size = sizeof(der_buffer);
 | 
				
			||||||
 | 
					    int i, j, n;
 | 
				
			||||||
 | 
					    char *p, *q;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Set to sane values
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    memset( buf, 0, sizeof(buf) );
 | 
				
			||||||
 | 
					    memset( der_buffer, 0, sizeof(der_buffer) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( argc == 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    usage:
 | 
				
			||||||
 | 
					        printf( USAGE );
 | 
				
			||||||
 | 
					        goto exit;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    opt.filename            = DFL_FILENAME;
 | 
				
			||||||
 | 
					    opt.output_file         = DFL_OUTPUT_FILENAME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for( i = 1; i < argc; i++ )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        p = argv[i];
 | 
				
			||||||
 | 
					        if( ( q = strchr( p, '=' ) ) == NULL )
 | 
				
			||||||
 | 
					            goto usage;
 | 
				
			||||||
 | 
					        *q++ = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        n = strlen( p );
 | 
				
			||||||
 | 
					        for( j = 0; j < n; j++ )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' )
 | 
				
			||||||
 | 
					                argv[i][j] |= 0x20;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if( strcmp( p, "filename" ) == 0 )
 | 
				
			||||||
 | 
					            opt.filename = q;
 | 
				
			||||||
 | 
					        else if( strcmp( p, "output_file" ) == 0 )
 | 
				
			||||||
 | 
					            opt.output_file = q;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            goto usage;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * 1.1. Load the PEM file
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    printf( "\n  . Loading the PEM file ..." );
 | 
				
			||||||
 | 
					    fflush( stdout );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = load_file( opt.filename, &pem_buffer, &pem_size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ret != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef POLARSSL_ERROR_C
 | 
				
			||||||
 | 
					        error_strerror( ret, buf, 1024 );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        printf( " failed\n  !  load_file returned %d - %s\n\n", ret, buf );
 | 
				
			||||||
 | 
					        goto exit;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf( " ok\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * 1.2. Convert from PEM to DER
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    printf( "  . Converting from PEM to DER ..." );
 | 
				
			||||||
 | 
					    fflush( stdout );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = convert_pem_to_der( pem_buffer, pem_size, der_buffer, &der_size ) ) != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef POLARSSL_ERROR_C
 | 
				
			||||||
 | 
					        error_strerror( ret, buf, 1024 );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        printf( " failed\n  !  convert_pem_to_der %d - %s\n\n", ret, buf );
 | 
				
			||||||
 | 
					        goto exit;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf( " ok\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * 1.3. Write the DER file
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    printf( "  . Writing the DER file ..." );
 | 
				
			||||||
 | 
					    fflush( stdout );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = write_file( opt.output_file, der_buffer, der_size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ret != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef POLARSSL_ERROR_C
 | 
				
			||||||
 | 
					        error_strerror( ret, buf, 1024 );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        printf( " failed\n  !  write_file returned %d - %s\n\n", ret, buf );
 | 
				
			||||||
 | 
					        goto exit;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf( " ok\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exit:
 | 
				
			||||||
 | 
					    free( pem_buffer );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
					    printf( "  + Press Enter to exit this program.\n" );
 | 
				
			||||||
 | 
					    fflush( stdout ); getchar();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( ret );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif /* POLARSSL_BASE64_C && POLARSSL_FS_IO */
 | 
				
			||||||
@@ -16,6 +16,9 @@ target_link_libraries(cert_app ${libs})
 | 
				
			|||||||
add_executable(crl_app crl_app.c)
 | 
					add_executable(crl_app crl_app.c)
 | 
				
			||||||
target_link_libraries(crl_app ${libs})
 | 
					target_link_libraries(crl_app ${libs})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install(TARGETS cert_app crl_app
 | 
					add_executable(cert_req cert_req.c)
 | 
				
			||||||
 | 
					target_link_libraries(cert_req ${libs})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install(TARGETS cert_app crl_app cert_req
 | 
				
			||||||
        DESTINATION "bin"
 | 
					        DESTINATION "bin"
 | 
				
			||||||
        PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
 | 
					        PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,8 @@
 | 
				
			|||||||
#define DFL_DEBUG_LEVEL         0
 | 
					#define DFL_DEBUG_LEVEL         0
 | 
				
			||||||
#define DFL_OUTPUT_FILENAME     "cert.req"
 | 
					#define DFL_OUTPUT_FILENAME     "cert.req"
 | 
				
			||||||
#define DFL_SUBJECT_NAME        "CN=Cert,O=PolarSSL,C=NL"
 | 
					#define DFL_SUBJECT_NAME        "CN=Cert,O=PolarSSL,C=NL"
 | 
				
			||||||
 | 
					#define DFL_KEY_USAGE           0
 | 
				
			||||||
 | 
					#define DFL_NS_CERT_TYPE        0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * global options
 | 
					 * global options
 | 
				
			||||||
@@ -54,53 +56,32 @@ struct options
 | 
				
			|||||||
    int debug_level;            /* level of debugging                   */
 | 
					    int debug_level;            /* level of debugging                   */
 | 
				
			||||||
    char *output_file;          /* where to store the constructed key file  */
 | 
					    char *output_file;          /* where to store the constructed key file  */
 | 
				
			||||||
    char *subject_name;         /* subject name for certificate request */
 | 
					    char *subject_name;         /* subject name for certificate request */
 | 
				
			||||||
 | 
					    unsigned char key_usage;    /* key usage flags                      */
 | 
				
			||||||
 | 
					    unsigned char ns_cert_type; /* NS cert type                         */
 | 
				
			||||||
} opt;
 | 
					} opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void my_debug( void *ctx, int level, const char *str )
 | 
					int write_certificate_request( x509_csr *req, char *output_file )
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if( level < opt.debug_level )
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        fprintf( (FILE *) ctx, "%s", str );
 | 
					 | 
				
			||||||
        fflush(  (FILE *) ctx  );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void write_certificate_request( rsa_context *rsa, x509_req_name *req_name,
 | 
					 | 
				
			||||||
                                char *output_file )
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
    FILE *f;
 | 
					    FILE *f;
 | 
				
			||||||
    unsigned char output_buf[4096];
 | 
					    unsigned char output_buf[4096];
 | 
				
			||||||
    unsigned char base_buf[4096];
 | 
					    size_t len = 0;
 | 
				
			||||||
    unsigned char *c;
 | 
					 | 
				
			||||||
    int ret;
 | 
					 | 
				
			||||||
    size_t len = 0, olen = 4096;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(output_buf, 0, 4096);
 | 
					    memset( output_buf, 0, 4096 );
 | 
				
			||||||
    ret = x509_write_cert_req( output_buf, 4096, rsa, req_name, POLARSSL_MD_SHA1 );
 | 
					    if( ( ret = x509write_csr_pem( req, output_buf, 4096 ) ) < 0 )
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( ret < 0 )
 | 
					    len = strlen( (char *) output_buf );
 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    len = ret;
 | 
					    if( ( f = fopen( output_file, "w" ) ) == NULL )
 | 
				
			||||||
    c = output_buf + 4095 - len;
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    base64_encode( base_buf, &olen, c, len );
 | 
					    if( fwrite( output_buf, 1, len, f ) != len )
 | 
				
			||||||
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c = base_buf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    f = fopen( output_file, "w" );
 | 
					 | 
				
			||||||
    fprintf(f, "-----BEGIN CERTIFICATE REQUEST-----\n");
 | 
					 | 
				
			||||||
    while (olen)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        int use_len = olen;
 | 
					 | 
				
			||||||
        if (use_len > 64) use_len = 64;
 | 
					 | 
				
			||||||
        fwrite( c, 1, use_len, f );
 | 
					 | 
				
			||||||
        olen -= use_len;
 | 
					 | 
				
			||||||
        c += use_len;
 | 
					 | 
				
			||||||
        fprintf(f, "\n");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    fprintf(f, "-----END CERTIFICATE REQUEST-----\n");
 | 
					 | 
				
			||||||
    fclose(f);
 | 
					    fclose(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USAGE \
 | 
					#define USAGE \
 | 
				
			||||||
@@ -110,6 +91,24 @@ void write_certificate_request( rsa_context *rsa, x509_req_name *req_name,
 | 
				
			|||||||
    "    debug_level=%%d      default: 0 (disabled)\n"  \
 | 
					    "    debug_level=%%d      default: 0 (disabled)\n"  \
 | 
				
			||||||
    "    output_file=%%s      default: cert.req\n"      \
 | 
					    "    output_file=%%s      default: cert.req\n"      \
 | 
				
			||||||
    "    subject_name=%%s     default: CN=Cert,O=PolarSSL,C=NL\n"   \
 | 
					    "    subject_name=%%s     default: CN=Cert,O=PolarSSL,C=NL\n"   \
 | 
				
			||||||
 | 
					    "    key_usage=%%s        default: (empty)\n"       \
 | 
				
			||||||
 | 
					    "                        Comma-separated-list of values:\n"     \
 | 
				
			||||||
 | 
					    "                          digital_signature\n"     \
 | 
				
			||||||
 | 
					    "                          non_repudiation\n"       \
 | 
				
			||||||
 | 
					    "                          key_encipherment\n"      \
 | 
				
			||||||
 | 
					    "                          data_encipherment\n"     \
 | 
				
			||||||
 | 
					    "                          key_agreement\n"         \
 | 
				
			||||||
 | 
					    "                          key_certificate_sign\n"  \
 | 
				
			||||||
 | 
					    "                          crl_sign\n"              \
 | 
				
			||||||
 | 
					    "    ns_cert_type=%%s     default: (empty)\n"       \
 | 
				
			||||||
 | 
					    "                        Comma-separated-list of values:\n"     \
 | 
				
			||||||
 | 
					    "                          ssl_client\n"            \
 | 
				
			||||||
 | 
					    "                          ssl_server\n"            \
 | 
				
			||||||
 | 
					    "                          email\n"                 \
 | 
				
			||||||
 | 
					    "                          object_signing\n"        \
 | 
				
			||||||
 | 
					    "                          ssl_ca\n"                \
 | 
				
			||||||
 | 
					    "                          email_ca\n"              \
 | 
				
			||||||
 | 
					    "                          object_signing_ca\n"     \
 | 
				
			||||||
    "\n"
 | 
					    "\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_RSA_C) ||         \
 | 
					#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_RSA_C) ||         \
 | 
				
			||||||
@@ -130,16 +129,14 @@ int main( int argc, char *argv[] )
 | 
				
			|||||||
    rsa_context rsa;
 | 
					    rsa_context rsa;
 | 
				
			||||||
    char buf[1024];
 | 
					    char buf[1024];
 | 
				
			||||||
    int i, j, n;
 | 
					    int i, j, n;
 | 
				
			||||||
    char *p, *q;
 | 
					    char *p, *q, *r;
 | 
				
			||||||
    char *s, *c, *end;
 | 
					    x509_csr req;
 | 
				
			||||||
    int in_tag;
 | 
					 | 
				
			||||||
    char *oid = NULL;
 | 
					 | 
				
			||||||
    x509_req_name *req_name = NULL;
 | 
					 | 
				
			||||||
    x509_req_name *cur = req_name;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * Set to sane values
 | 
					     * Set to sane values
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					    x509write_csr_init( &req );
 | 
				
			||||||
 | 
					    x509write_csr_set_md_alg( &req, POLARSSL_MD_SHA1 );
 | 
				
			||||||
    memset( &rsa, 0, sizeof( rsa_context ) );
 | 
					    memset( &rsa, 0, sizeof( rsa_context ) );
 | 
				
			||||||
    memset( buf, 0, 1024 );
 | 
					    memset( buf, 0, 1024 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,6 +144,7 @@ int main( int argc, char *argv[] )
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
    usage:
 | 
					    usage:
 | 
				
			||||||
        printf( USAGE );
 | 
					        printf( USAGE );
 | 
				
			||||||
 | 
					        ret = 1;
 | 
				
			||||||
        goto exit;
 | 
					        goto exit;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -154,6 +152,8 @@ int main( int argc, char *argv[] )
 | 
				
			|||||||
    opt.debug_level         = DFL_DEBUG_LEVEL;
 | 
					    opt.debug_level         = DFL_DEBUG_LEVEL;
 | 
				
			||||||
    opt.output_file         = DFL_OUTPUT_FILENAME;
 | 
					    opt.output_file         = DFL_OUTPUT_FILENAME;
 | 
				
			||||||
    opt.subject_name        = DFL_SUBJECT_NAME;
 | 
					    opt.subject_name        = DFL_SUBJECT_NAME;
 | 
				
			||||||
 | 
					    opt.key_usage           = DFL_KEY_USAGE;
 | 
				
			||||||
 | 
					    opt.ns_cert_type        = DFL_NS_CERT_TYPE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for( i = 1; i < argc; i++ )
 | 
					    for( i = 1; i < argc; i++ )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -184,81 +184,80 @@ int main( int argc, char *argv[] )
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            opt.subject_name = q;
 | 
					            opt.subject_name = q;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        else if( strcmp( p, "key_usage" ) == 0 )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            while( q != NULL )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if( ( r = strchr( q, ',' ) ) != NULL )
 | 
				
			||||||
 | 
					                    *r++ = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if( strcmp( q, "digital_signature" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.key_usage |= KU_DIGITAL_SIGNATURE;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "non_repudiation" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.key_usage |= KU_NON_REPUDIATION;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "key_encipherment" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.key_usage |= KU_KEY_ENCIPHERMENT;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "data_encipherment" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.key_usage |= KU_DATA_ENCIPHERMENT;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "key_agreement" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.key_usage |= KU_KEY_AGREEMENT;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "key_cert_sign" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.key_usage |= KU_KEY_CERT_SIGN;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "crl_sign" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.key_usage |= KU_CRL_SIGN;
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                q = r;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if( strcmp( p, "ns_cert_type" ) == 0 )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            while( q != NULL )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if( ( r = strchr( q, ',' ) ) != NULL )
 | 
				
			||||||
 | 
					                    *r++ = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if( strcmp( q, "ssl_client" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.ns_cert_type |= NS_CERT_TYPE_SSL_CLIENT;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "ssl_server" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.ns_cert_type |= NS_CERT_TYPE_SSL_SERVER;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "email" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.ns_cert_type |= NS_CERT_TYPE_EMAIL;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "object_signing" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.ns_cert_type |= NS_CERT_TYPE_OBJECT_SIGNING;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "ssl_ca" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.ns_cert_type |= NS_CERT_TYPE_SSL_CA;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "email_ca" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.ns_cert_type |= NS_CERT_TYPE_EMAIL_CA;
 | 
				
			||||||
 | 
					                else if( strcmp( q, "object_signing_ca" ) == 0 )
 | 
				
			||||||
 | 
					                    opt.ns_cert_type |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                q = r;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            goto usage;
 | 
					            goto usage;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( opt.key_usage )
 | 
				
			||||||
 | 
					        x509write_csr_set_key_usage( &req, opt.key_usage );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( opt.ns_cert_type )
 | 
				
			||||||
 | 
					        x509write_csr_set_ns_cert_type( &req, opt.ns_cert_type );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * 1.0. Check the subject name for validity
 | 
					     * 1.0. Check the subject name for validity
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    s = opt.subject_name;
 | 
					    if( ( ret = x509write_csr_set_subject_name( &req, opt.subject_name ) ) != 0 )
 | 
				
			||||||
    end = s + strlen( s );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    c = s;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    in_tag = 1;
 | 
					 | 
				
			||||||
    while( c <= end )
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if( in_tag && *c == '=' )
 | 
					#ifdef POLARSSL_ERROR_C
 | 
				
			||||||
        {
 | 
					        error_strerror( ret, buf, 1024 );
 | 
				
			||||||
            if( memcmp( s, "CN", 2 ) == 0 && c - s == 2 )
 | 
					#endif
 | 
				
			||||||
                oid = OID_AT_CN;
 | 
					        printf( " failed\n  !  x509write_csr_set_subject_name returned %d - %s\n\n", ret, buf );
 | 
				
			||||||
            else if( memcmp( s, "C", 1 ) == 0 && c - s == 1 )
 | 
					        goto exit;
 | 
				
			||||||
                oid = OID_AT_COUNTRY;
 | 
					 | 
				
			||||||
            else if( memcmp( s, "O", 1 ) == 0 && c - s == 1 )
 | 
					 | 
				
			||||||
                oid = OID_AT_ORGANIZATION;
 | 
					 | 
				
			||||||
            else if( memcmp( s, "L", 1 ) == 0 && c - s == 1 )
 | 
					 | 
				
			||||||
                oid = OID_AT_LOCALITY;
 | 
					 | 
				
			||||||
            else if( memcmp( s, "R", 1 ) == 0 && c - s == 1 )
 | 
					 | 
				
			||||||
                oid = OID_PKCS9_EMAIL;
 | 
					 | 
				
			||||||
            else if( memcmp( s, "OU", 2 ) == 0 && c - s == 2 )
 | 
					 | 
				
			||||||
                oid = OID_AT_ORG_UNIT;
 | 
					 | 
				
			||||||
            else if( memcmp( s, "ST", 2 ) == 0 && c - s == 2 )
 | 
					 | 
				
			||||||
                oid = OID_AT_STATE;
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                printf("Failed to parse subject name.\n");
 | 
					 | 
				
			||||||
                goto exit;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            s = c + 1;
 | 
					 | 
				
			||||||
            in_tag = 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if( !in_tag && ( *c == ',' || c == end ) )
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if( c - s > 127 )
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                printf("Name too large for buffer.\n");
 | 
					 | 
				
			||||||
                goto exit;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if( cur == NULL )
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                req_name = malloc( sizeof(x509_req_name) );
 | 
					 | 
				
			||||||
                cur = req_name;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                cur->next = malloc( sizeof(x509_req_name) );
 | 
					 | 
				
			||||||
                cur = cur->next;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if( cur == NULL )
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                printf( "Failed to allocate memory.\n" );
 | 
					 | 
				
			||||||
                goto exit;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            memset( cur, 0, sizeof(x509_req_name) );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            strncpy( cur->oid, oid, strlen( oid ) );
 | 
					 | 
				
			||||||
            strncpy( cur->name, s, c - s );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            s = c + 1;
 | 
					 | 
				
			||||||
            in_tag = 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        c++;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
@@ -275,16 +274,32 @@ int main( int argc, char *argv[] )
 | 
				
			|||||||
        error_strerror( ret, buf, 1024 );
 | 
					        error_strerror( ret, buf, 1024 );
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        printf( " failed\n  !  x509parse_key_rsa returned %d - %s\n\n", ret, buf );
 | 
					        printf( " failed\n  !  x509parse_key_rsa returned %d - %s\n\n", ret, buf );
 | 
				
			||||||
        rsa_free( &rsa );
 | 
					        goto exit;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x509write_csr_set_rsa_key( &req, &rsa );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf( " ok\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * 1.2. Writing the request
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    printf( "  . Writing the certificate request ..." );
 | 
				
			||||||
 | 
					    fflush( stdout );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = write_certificate_request( &req, opt.output_file ) ) != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef POLARSSL_ERROR_C
 | 
				
			||||||
 | 
					        error_strerror( ret, buf, 1024 );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        printf( " failed\n  !  write_certifcate_request %d - %s\n\n", ret, buf );
 | 
				
			||||||
        goto exit;
 | 
					        goto exit;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf( " ok\n" );
 | 
					    printf( " ok\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    write_certificate_request( &rsa, req_name, opt.output_file );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
exit:
 | 
					exit:
 | 
				
			||||||
 | 
					    x509write_csr_free( &req );
 | 
				
			||||||
    rsa_free( &rsa );
 | 
					    rsa_free( &rsa );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_WIN32)
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ my @low_level_modules = ( "AES", "ASN1", "BLOWFISH", "CAMELLIA", "BIGNUM",
 | 
				
			|||||||
                          "PADLOCK", "DES", "NET", "CTR_DRBG", "ENTROPY",
 | 
					                          "PADLOCK", "DES", "NET", "CTR_DRBG", "ENTROPY",
 | 
				
			||||||
                          "MD2", "MD4", "MD5", "SHA1", "SHA256", "SHA512", "GCM" );
 | 
					                          "MD2", "MD4", "MD5", "SHA1", "SHA256", "SHA512", "GCM" );
 | 
				
			||||||
my @high_level_modules = ( "PEM", "X509", "DHM", "RSA", "ECP", "MD", "CIPHER", "SSL",
 | 
					my @high_level_modules = ( "PEM", "X509", "DHM", "RSA", "ECP", "MD", "CIPHER", "SSL",
 | 
				
			||||||
                           "PK", "PKCS12", "PKCS5" );
 | 
					                           "PK", "PKCS12", "PKCS5", "X509WRITE" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
my $line_separator = $/;
 | 
					my $line_separator = $/;
 | 
				
			||||||
undef $/;
 | 
					undef $/;
 | 
				
			||||||
@@ -49,6 +49,7 @@ while (my $line = <GREP>)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    my $define_name = $module_name;
 | 
					    my $define_name = $module_name;
 | 
				
			||||||
    $define_name = "X509_PARSE" if ($define_name eq "X509");
 | 
					    $define_name = "X509_PARSE" if ($define_name eq "X509");
 | 
				
			||||||
 | 
					    $define_name = "X509_WRITE" if ($define_name eq "X509WRITE");
 | 
				
			||||||
    $define_name = "ASN1_PARSE" if ($define_name eq "ASN1");
 | 
					    $define_name = "ASN1_PARSE" if ($define_name eq "ASN1");
 | 
				
			||||||
    $define_name = "SSL_TLS" if ($define_name eq "SSL");
 | 
					    $define_name = "SSL_TLS" if ($define_name eq "SSL");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,27 +1,27 @@
 | 
				
			|||||||
Certificate Request check Server1 SHA1
 | 
					Certificate Request check Server1 SHA1
 | 
				
			||||||
depends_on:POLARSSL_SHA1_C
 | 
					depends_on:POLARSSL_SHA1_C
 | 
				
			||||||
x509_cert_req_check:"data_files/server1.key":POLARSSL_MD_SHA1:"data_files/server1.req.sha1"
 | 
					x509_csr_check:"data_files/server1.key":POLARSSL_MD_SHA1:"data_files/server1.req.sha1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Certificate Request check Server1 SHA224
 | 
					Certificate Request check Server1 SHA224
 | 
				
			||||||
depends_on:POLARSSL_SHA256_C
 | 
					depends_on:POLARSSL_SHA256_C
 | 
				
			||||||
x509_cert_req_check:"data_files/server1.key":POLARSSL_MD_SHA224:"data_files/server1.req.sha224"
 | 
					x509_csr_check:"data_files/server1.key":POLARSSL_MD_SHA224:"data_files/server1.req.sha224"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Certificate Request check Server1 SHA256
 | 
					Certificate Request check Server1 SHA256
 | 
				
			||||||
depends_on:POLARSSL_SHA256_C
 | 
					depends_on:POLARSSL_SHA256_C
 | 
				
			||||||
x509_cert_req_check:"data_files/server1.key":POLARSSL_MD_SHA256:"data_files/server1.req.sha256"
 | 
					x509_csr_check:"data_files/server1.key":POLARSSL_MD_SHA256:"data_files/server1.req.sha256"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Certificate Request check Server1 SHA384
 | 
					Certificate Request check Server1 SHA384
 | 
				
			||||||
depends_on:POLARSSL_SHA512_C
 | 
					depends_on:POLARSSL_SHA512_C
 | 
				
			||||||
x509_cert_req_check:"data_files/server1.key":POLARSSL_MD_SHA384:"data_files/server1.req.sha384"
 | 
					x509_csr_check:"data_files/server1.key":POLARSSL_MD_SHA384:"data_files/server1.req.sha384"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Certificate Request check Server1 SHA512
 | 
					Certificate Request check Server1 SHA512
 | 
				
			||||||
depends_on:POLARSSL_SHA512_C
 | 
					depends_on:POLARSSL_SHA512_C
 | 
				
			||||||
x509_cert_req_check:"data_files/server1.key":POLARSSL_MD_SHA512:"data_files/server1.req.sha512"
 | 
					x509_csr_check:"data_files/server1.key":POLARSSL_MD_SHA512:"data_files/server1.req.sha512"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Certificate Request check Server1 MD4
 | 
					Certificate Request check Server1 MD4
 | 
				
			||||||
depends_on:POLARSSL_MD4_C
 | 
					depends_on:POLARSSL_MD4_C
 | 
				
			||||||
x509_cert_req_check:"data_files/server1.key":POLARSSL_MD_MD4:"data_files/server1.req.md4"
 | 
					x509_csr_check:"data_files/server1.key":POLARSSL_MD_MD4:"data_files/server1.req.md4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Certificate Request check Server1 MD5
 | 
					Certificate Request check Server1 MD5
 | 
				
			||||||
depends_on:POLARSSL_MD5_C
 | 
					depends_on:POLARSSL_MD5_C
 | 
				
			||||||
x509_cert_req_check:"data_files/server1.key":POLARSSL_MD_MD5:"data_files/server1.req.md5"
 | 
					x509_csr_check:"data_files/server1.key":POLARSSL_MD_MD5:"data_files/server1.req.md5"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,36 +11,19 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* BEGIN_CASE */
 | 
					/* BEGIN_CASE */
 | 
				
			||||||
void x509_cert_req_check( char *key_file, int md_type,
 | 
					void x509_csr_check( char *key_file, int md_type,
 | 
				
			||||||
                          char *cert_req_check_file )
 | 
					                          char *cert_req_check_file )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    rsa_context rsa;
 | 
					    rsa_context rsa;
 | 
				
			||||||
    pem_context pem;
 | 
					    pem_context pem;
 | 
				
			||||||
    x509_req_name req_name, *cur;
 | 
					    x509_csr req;
 | 
				
			||||||
    unsigned char *c;
 | 
					    unsigned char *c;
 | 
				
			||||||
    unsigned char buf[4000];
 | 
					    unsigned char buf[4000];
 | 
				
			||||||
    unsigned char check_buf[4000];
 | 
					    unsigned char check_buf[4000];
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    size_t olen = 2000;
 | 
					    size_t olen = 2000;
 | 
				
			||||||
    FILE *f;
 | 
					    FILE *f;
 | 
				
			||||||
 | 
					    char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
 | 
				
			||||||
    cur = &req_name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memset( cur, 0, sizeof(x509_req_name) );
 | 
					 | 
				
			||||||
    strcpy( cur->oid, OID_AT_CN );
 | 
					 | 
				
			||||||
    strcpy( cur->name, "PolarSSL Server 1" );
 | 
					 | 
				
			||||||
    cur->next = malloc( sizeof(x509_req_name) );
 | 
					 | 
				
			||||||
    cur = cur->next;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memset( cur, 0, sizeof(x509_req_name) );
 | 
					 | 
				
			||||||
    strcpy( cur->oid, OID_AT_ORGANIZATION );
 | 
					 | 
				
			||||||
    strcpy( cur->name, "PolarSSL" );
 | 
					 | 
				
			||||||
    cur->next = malloc( sizeof(x509_req_name) );
 | 
					 | 
				
			||||||
    cur = cur->next;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memset( cur, 0, sizeof(x509_req_name) );
 | 
					 | 
				
			||||||
    strcpy( cur->oid, OID_AT_COUNTRY );
 | 
					 | 
				
			||||||
    strcpy( cur->name, "NL" );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset( &rsa, 0, sizeof(rsa_context) );
 | 
					    memset( &rsa, 0, sizeof(rsa_context) );
 | 
				
			||||||
    ret = x509parse_keyfile_rsa( &rsa, key_file, NULL );
 | 
					    ret = x509parse_keyfile_rsa( &rsa, key_file, NULL );
 | 
				
			||||||
@@ -48,7 +31,12 @@ void x509_cert_req_check( char *key_file, int md_type,
 | 
				
			|||||||
    if( ret != 0 )
 | 
					    if( ret != 0 )
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = x509_write_cert_req( buf, 4000, &rsa, &req_name, md_type );
 | 
					    x509write_csr_init( &req );
 | 
				
			||||||
 | 
					    x509write_csr_set_md_alg( &req, md_type );
 | 
				
			||||||
 | 
					    x509write_csr_set_rsa_key( &req, &rsa );
 | 
				
			||||||
 | 
					    TEST_ASSERT( x509write_csr_set_subject_name( &req, subject_name ) == 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = x509write_csr_der( &req, buf, 4000 );
 | 
				
			||||||
    TEST_ASSERT( ret >= 0 );
 | 
					    TEST_ASSERT( ret >= 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c = buf + 3999 - ret;
 | 
					    c = buf + 3999 - ret;
 | 
				
			||||||
@@ -64,12 +52,7 @@ void x509_cert_req_check( char *key_file, int md_type,
 | 
				
			|||||||
    TEST_ASSERT( memcmp( c, pem.buf, pem.buflen ) == 0 );
 | 
					    TEST_ASSERT( memcmp( c, pem.buf, pem.buflen ) == 0 );
 | 
				
			||||||
    TEST_ASSERT( pem.buflen == (size_t) ret );
 | 
					    TEST_ASSERT( pem.buflen == (size_t) ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while( ( cur = req_name.next ) != NULL )
 | 
					    x509write_csr_free( &req );
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        req_name.next = cur->next;
 | 
					 | 
				
			||||||
        free( cur );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    rsa_free( &rsa );
 | 
					    rsa_free( &rsa );
 | 
				
			||||||
    pem_free( &pem );
 | 
					    pem_free( &pem );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user