Split up X509 files into smaller modules
This commit is contained in:
parent
ace02867f6
commit
7c6b2c320e
@ -287,7 +287,7 @@
|
||||
*
|
||||
* Enable the RSA-PSK based ciphersuite modes in SSL / TLS
|
||||
* (NOT YET IMPLEMENTED)
|
||||
* Requires: POLARSSL_RSA_C, POLARSSL_X509_PARSE_C, POLARSSL_PKCS1_V15
|
||||
* Requires: POLARSSL_RSA_C, POLARSSL_X509_CRT_PARSE_C, POLARSSL_PKCS1_V15
|
||||
*
|
||||
* This enables the following ciphersuites (if other requisites are
|
||||
* enabled as well):
|
||||
@ -307,7 +307,7 @@
|
||||
*
|
||||
* Enable the RSA-only based ciphersuite modes in SSL / TLS
|
||||
*
|
||||
* Requires: POLARSSL_RSA_C, POLARSSL_X509_PARSE_C, POLARSSL_PKCS1_V15
|
||||
* Requires: POLARSSL_RSA_C, POLARSSL_X509_CRT_PARSE_C, POLARSSL_PKCS1_V15
|
||||
*
|
||||
* This enables the following ciphersuites (if other requisites are
|
||||
* enabled as well):
|
||||
@ -332,7 +332,7 @@
|
||||
*
|
||||
* Enable the DHE-RSA based ciphersuite modes in SSL / TLS
|
||||
*
|
||||
* Requires: POLARSSL_DHM_C, POLARSSL_RSA_C, POLARSSL_X509_PARSE_C,
|
||||
* Requires: POLARSSL_DHM_C, POLARSSL_RSA_C, POLARSSL_X509_CRT_PARSE_C,
|
||||
* POLARSSL_PKCS1_V15
|
||||
*
|
||||
* This enables the following ciphersuites (if other requisites are
|
||||
@ -354,7 +354,7 @@
|
||||
*
|
||||
* Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS
|
||||
*
|
||||
* Requires: POLARSSL_ECDH_C, POLARSSL_RSA_C, POLARSSL_X509_PARSE_C,
|
||||
* Requires: POLARSSL_ECDH_C, POLARSSL_RSA_C, POLARSSL_X509_CRT_PARSE_C,
|
||||
* POLARSSL_PKCS1_V15
|
||||
*
|
||||
* This enables the following ciphersuites (if other requisites are
|
||||
@ -377,7 +377,7 @@
|
||||
*
|
||||
* Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS
|
||||
*
|
||||
* Requires: POLARSSL_ECDH_C, POLARSSL_ECDSA_C, POLARSSL_X509_PARSE_C
|
||||
* Requires: POLARSSL_ECDH_C, POLARSSL_ECDSA_C, POLARSSL_X509_CRT_PARSE_C
|
||||
*
|
||||
* This enables the following ciphersuites (if other requisites are
|
||||
* enabled as well):
|
||||
@ -1413,34 +1413,104 @@
|
||||
#define POLARSSL_VERSION_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_PARSE_C
|
||||
* \def POLARSSL_X509_USE_C
|
||||
*
|
||||
* Enable X.509 certificate parsing.
|
||||
* Enable X.509 core for using certificates
|
||||
*
|
||||
* Module: library/x509parse.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
* Module: library/x509.c
|
||||
* Caller: library/x509_crl.c
|
||||
* library/x509_crt.c
|
||||
* library/x509_csr.c
|
||||
*
|
||||
* Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_OID_C,
|
||||
* POLARSSL_PK_PARSE_C
|
||||
*
|
||||
* This module is required for X.509 certificate parsing.
|
||||
* This module is required for the X.509 parsing modules.
|
||||
*/
|
||||
#define POLARSSL_X509_PARSE_C
|
||||
#define POLARSSL_X509_USE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_WRITE_C
|
||||
* \def POLARSSL_X509_CRT_PARSE_C
|
||||
*
|
||||
* Enable X.509 buffer writing.
|
||||
* Enable X.509 certificate parsing.
|
||||
*
|
||||
* Module: library/x509write.c
|
||||
* Module: library/x509_crt.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
*
|
||||
* Requires: POLARSSL_X509_USE_C
|
||||
*
|
||||
* This module is required for X.509 certificate parsing.
|
||||
*/
|
||||
#define POLARSSL_X509_CRT_PARSE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_CRL_PARSE_C
|
||||
*
|
||||
* Enable X.509 CRL parsing.
|
||||
*
|
||||
* Module: library/x509_crl.c
|
||||
* Caller: library/x509_crt.c
|
||||
*
|
||||
* Requires: POLARSSL_X509_USE_C
|
||||
*
|
||||
* This module is required for X.509 CRL parsing.
|
||||
*/
|
||||
#define POLARSSL_X509_CRL_PARSE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_CSR_PARSE_C
|
||||
*
|
||||
* Enable X.509 Certificate Signing Request (CSR) parsing.
|
||||
*
|
||||
* Module: library/x509_csr.c
|
||||
* Caller: library/x509_crt_write.c
|
||||
*
|
||||
* Requires: POLARSSL_X509_USE_C
|
||||
*
|
||||
* This module is used for reading X.509 certificate request.
|
||||
*/
|
||||
#define POLARSSL_X509_CSR_PARSE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_CREATE_C
|
||||
*
|
||||
* Enable X.509 core for creating certificates
|
||||
*
|
||||
* Module: library/x509_create.c
|
||||
*
|
||||
* Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C, POLARSSL_PK_WRITE_C
|
||||
*
|
||||
* This module is the basis for creating X.509 certificates and CSRs.
|
||||
*/
|
||||
#define POLARSSL_X509_CREATE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_CRT_WRITE_C
|
||||
*
|
||||
* Enable creating X.509 certificates.
|
||||
*
|
||||
* Module: library/x509_crt_write.c
|
||||
*
|
||||
* Requires: POLARSSL_CREATE_C
|
||||
*
|
||||
* This module is required for X.509 certificate creation.
|
||||
*/
|
||||
#define POLARSSL_X509_CRT_WRITE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_CSR_WRITE_C
|
||||
*
|
||||
* Enable creating X.509 Certificate Signing Requests (CSR)
|
||||
*
|
||||
* Module: library/x509_csr_write.c
|
||||
*
|
||||
* Requires: POLARSSL_CREATE_C
|
||||
*
|
||||
* This module is required for X.509 certificate request writing.
|
||||
*/
|
||||
#define POLARSSL_X509_WRITE_C
|
||||
#define POLARSSL_X509_CSR_WRITE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_XTEA_C
|
||||
@ -1566,30 +1636,30 @@
|
||||
|
||||
#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
|
||||
( !defined(POLARSSL_DHM_C) || !defined(POLARSSL_RSA_C) || \
|
||||
!defined(POLARSSL_X509_PARSE_C) || !defined(POLARSSL_PKCS1_V15) )
|
||||
!defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_PKCS1_V15) )
|
||||
#error "POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
|
||||
( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_RSA_C) || \
|
||||
!defined(POLARSSL_X509_PARSE_C) || !defined(POLARSSL_PKCS1_V15) )
|
||||
!defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_PKCS1_V15) )
|
||||
#error "POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
|
||||
( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_ECDSA_C) || \
|
||||
!defined(POLARSSL_X509_PARSE_C) )
|
||||
!defined(POLARSSL_X509_CRT_PARSE_C) )
|
||||
#error "POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
|
||||
( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_PARSE_C) || \
|
||||
( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ||\
|
||||
!defined(POLARSSL_PKCS1_V15) )
|
||||
#error "POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \
|
||||
( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_PARSE_C) || \
|
||||
( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ||\
|
||||
!defined(POLARSSL_PKCS1_V15) )
|
||||
#error "POLARSSL_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
@ -1668,16 +1738,36 @@
|
||||
#error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C) && ( !defined(POLARSSL_BIGNUM_C) || \
|
||||
#if defined(POLARSSL_X509_USE_C) && ( !defined(POLARSSL_BIGNUM_C) || \
|
||||
!defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_PARSE_C) || \
|
||||
!defined(POLARSSL_PK_PARSE_C) )
|
||||
#error "POLARSSL_X509_PARSE_C defined, but not all prerequisites"
|
||||
#error "POLARSSL_X509_USE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_WRITE_C) && ( !defined(POLARSSL_BIGNUM_C) || \
|
||||
!defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_WRITE_C) || \
|
||||
!defined(POLARSSL_RSA_C) || !defined(POLARSSL_PK_WRITE_C) )
|
||||
#error "POLARSSL_X509_WRITE_C defined, but not all prerequisites"
|
||||
#if defined(POLARSSL_X509_CREATE_C) && ( !defined(POLARSSL_BIGNUM_C) || \
|
||||
!defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_WRITE_C) || \
|
||||
!defined(POLARSSL_PK_WRITE_C) )
|
||||
#error "POLARSSL_X509_CREATE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) )
|
||||
#error "POLARSSL_X509_CRT_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_CRL_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) )
|
||||
#error "POLARSSL_X509_CRL_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_CSR_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) )
|
||||
#error "POLARSSL_X509_CSR_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_CRT_WRITE_C) && ( !defined(POLARSSL_X509_CREATE_C) )
|
||||
#error "POLARSSL_X509_CRT_WRITE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_CSR_WRITE_C) && ( !defined(POLARSSL_X509_CREATE_C) )
|
||||
#error "POLARSSL_X509_CSR_WRITE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#endif /* config.h */
|
||||
|
@ -54,7 +54,7 @@
|
||||
debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X );
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
#define SSL_DEBUG_CRT( level, text, crt ) \
|
||||
debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt );
|
||||
#endif
|
||||
@ -99,7 +99,7 @@ void debug_print_ecp( const ssl_context *ssl, int level,
|
||||
const char *text, const ecp_point *X );
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
void debug_print_crt( const ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const x509_cert *crt );
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "md.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
|
||||
#include "x509.h"
|
||||
#endif
|
||||
|
||||
@ -337,7 +337,7 @@ typedef struct {
|
||||
*/
|
||||
int oid_get_numeric_string( char *buf, size_t size, const asn1_buf *oid );
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
|
||||
/**
|
||||
* \brief Translate an X.509 extension OID into local values
|
||||
*
|
||||
|
@ -54,8 +54,12 @@
|
||||
#include "aes.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#include "x509.h"
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
#include "x509_crt.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_CRL_PARSE_C)
|
||||
#include "x509_crl.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_DHM_C)
|
||||
@ -406,9 +410,9 @@ struct _ssl_session
|
||||
unsigned char id[32]; /*!< session identifier */
|
||||
unsigned char master[48]; /*!< the master secret */
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
x509_cert *peer_cert; /*!< peer X.509 cert chain */
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
int verify_result; /*!< verification result */
|
||||
|
||||
#if defined(POLARSSL_SSL_SESSION_TICKETS)
|
||||
@ -579,7 +583,7 @@ struct _ssl_context
|
||||
void *p_sni; /*!< context for SNI extension */
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
int (*f_vrfy)(void *, x509_cert *, int, int *);
|
||||
void *p_vrfy; /*!< context for verification */
|
||||
#endif
|
||||
@ -642,12 +646,14 @@ struct _ssl_context
|
||||
pk_context *pk_key; /*!< own private key */
|
||||
int pk_key_own_alloc; /*!< did we allocate pk_key? */
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
x509_cert *own_cert; /*!< own X.509 certificate */
|
||||
x509_cert *ca_chain; /*!< own trusted CA chain */
|
||||
x509_crl *ca_crl; /*!< trusted CA CRLs */
|
||||
const char *peer_cn; /*!< expected peer CN */
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
#if defined(POLARSSL_X509_CRL_PARSE_C)
|
||||
x509_crl *ca_crl; /*!< trusted CA CRLs */
|
||||
#endif /* POLARSSL_X509_CRL_PARSE_C */
|
||||
|
||||
#if defined(POLARSSL_SSL_SESSION_TICKETS)
|
||||
/*
|
||||
@ -806,7 +812,7 @@ void ssl_set_endpoint( ssl_context *ssl, int endpoint );
|
||||
*/
|
||||
void ssl_set_authmode( ssl_context *ssl, int authmode );
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
/**
|
||||
* \brief Set the verification callback (Optional).
|
||||
*
|
||||
@ -821,7 +827,7 @@ void ssl_set_authmode( ssl_context *ssl, int authmode );
|
||||
void ssl_set_verify( ssl_context *ssl,
|
||||
int (*f_vrfy)(void *, x509_cert *, int, int *),
|
||||
void *p_vrfy );
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
/**
|
||||
* \brief Set the random number generator callback
|
||||
@ -941,7 +947,7 @@ void ssl_set_ciphersuites_for_version( ssl_context *ssl,
|
||||
const int *ciphersuites,
|
||||
int major, int minor );
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
/**
|
||||
* \brief Set the data required to verify peer certificate
|
||||
*
|
||||
@ -1011,7 +1017,7 @@ int ssl_set_own_cert_alt( ssl_context *ssl, x509_cert *own_cert,
|
||||
rsa_decrypt_func rsa_decrypt,
|
||||
rsa_sign_func rsa_sign,
|
||||
rsa_key_len_func rsa_key_len );
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
|
||||
/**
|
||||
@ -1272,7 +1278,7 @@ const char *ssl_get_ciphersuite( const ssl_context *ssl );
|
||||
*/
|
||||
const char *ssl_get_version( const ssl_context *ssl );
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
/**
|
||||
* \brief Return the peer certificate from the current connection
|
||||
*
|
||||
@ -1288,7 +1294,7 @@ const char *ssl_get_version( const ssl_context *ssl );
|
||||
* \return the current peer certificate
|
||||
*/
|
||||
const x509_cert *ssl_get_peer_cert( const ssl_context *ssl );
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
/**
|
||||
* \brief Save session in order to resume it later (client-side only)
|
||||
|
@ -50,7 +50,7 @@ struct _ssl_cache_entry
|
||||
time_t timestamp; /*!< entry timestamp */
|
||||
#endif
|
||||
ssl_session session; /*!< entry session */
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
x509_buf peer_cert; /*!< entry peer_cert */
|
||||
#endif
|
||||
ssl_cache_entry *next; /*!< chain pointer */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* \file x509.h
|
||||
*
|
||||
* \brief X.509 certificate and private key decoding
|
||||
* \brief X.509 generic defines and structures
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
@ -30,16 +30,18 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "asn1.h"
|
||||
#include "dhm.h"
|
||||
#include "md.h"
|
||||
#include "pk.h"
|
||||
|
||||
/**
|
||||
#if defined(POLARSSL_RSA_C)
|
||||
#include "rsa.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup x509_module
|
||||
* \{
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* \name X509 Error codes
|
||||
* \{
|
||||
*/
|
||||
@ -61,6 +63,9 @@
|
||||
#define POLARSSL_ERR_X509_INVALID_INPUT -0x2800 /**< Input invalid. */
|
||||
#define POLARSSL_ERR_X509_MALLOC_FAILED -0x2880 /**< Allocation of memory failed. */
|
||||
#define POLARSSL_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */
|
||||
#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 */
|
||||
|
||||
/**
|
||||
@ -174,124 +179,6 @@ typedef struct _x509_time
|
||||
}
|
||||
x509_time;
|
||||
|
||||
/**
|
||||
* Container for an X.509 certificate. The certificate may be chained.
|
||||
*/
|
||||
typedef struct _x509_cert
|
||||
{
|
||||
x509_buf raw; /**< The raw certificate data (DER). */
|
||||
x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
|
||||
|
||||
int version; /**< The X.509 version. (0=v1, 1=v2, 2=v3) */
|
||||
x509_buf serial; /**< Unique id for certificate issued by a specific CA. */
|
||||
x509_buf sig_oid1; /**< Signature algorithm, e.g. sha1RSA */
|
||||
|
||||
x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */
|
||||
x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */
|
||||
|
||||
x509_name issuer; /**< The parsed issuer data (named information object). */
|
||||
x509_name subject; /**< The parsed subject data (named information object). */
|
||||
|
||||
x509_time valid_from; /**< Start time of certificate validity. */
|
||||
x509_time valid_to; /**< End time of certificate validity. */
|
||||
|
||||
pk_context pk; /**< Container for the public key context. */
|
||||
|
||||
x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
|
||||
x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
|
||||
x509_buf v3_ext; /**< Optional X.509 v3 extensions. Only Basic Contraints are supported at this time. */
|
||||
x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */
|
||||
|
||||
int ext_types; /**< Bit string containing detected and parsed extensions */
|
||||
int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
|
||||
int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */
|
||||
|
||||
unsigned char key_usage; /**< Optional key usage extension value: See the values below */
|
||||
|
||||
x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
|
||||
|
||||
unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values below */
|
||||
|
||||
x509_buf sig_oid2; /**< Signature algorithm. Must match sig_oid1. */
|
||||
x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */
|
||||
md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */
|
||||
pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */;
|
||||
|
||||
struct _x509_cert *next; /**< Next certificate in the CA-chain. */
|
||||
}
|
||||
x509_cert;
|
||||
|
||||
/**
|
||||
* Certificate revocation list entry.
|
||||
* Contains the CA-specific serial numbers and revocation dates.
|
||||
*/
|
||||
typedef struct _x509_crl_entry
|
||||
{
|
||||
x509_buf raw;
|
||||
|
||||
x509_buf serial;
|
||||
|
||||
x509_time revocation_date;
|
||||
|
||||
x509_buf entry_ext;
|
||||
|
||||
struct _x509_crl_entry *next;
|
||||
}
|
||||
x509_crl_entry;
|
||||
|
||||
/**
|
||||
* Certificate revocation list structure.
|
||||
* Every CRL may have multiple entries.
|
||||
*/
|
||||
typedef struct _x509_crl
|
||||
{
|
||||
x509_buf raw; /**< The raw certificate data (DER). */
|
||||
x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
|
||||
|
||||
int version;
|
||||
x509_buf sig_oid1;
|
||||
|
||||
x509_buf issuer_raw; /**< The raw issuer data (DER). */
|
||||
|
||||
x509_name issuer; /**< The parsed issuer data (named information object). */
|
||||
|
||||
x509_time this_update;
|
||||
x509_time next_update;
|
||||
|
||||
x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */
|
||||
|
||||
x509_buf crl_ext;
|
||||
|
||||
x509_buf sig_oid2;
|
||||
x509_buf sig;
|
||||
md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */
|
||||
pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */;
|
||||
|
||||
struct _x509_crl *next;
|
||||
}
|
||||
x509_crl;
|
||||
|
||||
/**
|
||||
* Certificate Signing Request (CSR) structure.
|
||||
*/
|
||||
typedef struct _x509_csr
|
||||
{
|
||||
x509_buf raw; /**< The raw CSR data (DER). */
|
||||
x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */
|
||||
|
||||
int version;
|
||||
|
||||
x509_buf subject_raw; /**< The raw subject data (DER). */
|
||||
x509_name subject; /**< The parsed subject data (named information object). */
|
||||
|
||||
pk_context pk; /**< Container for the public key context. */
|
||||
|
||||
x509_buf sig_oid;
|
||||
x509_buf sig;
|
||||
md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */
|
||||
pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */;
|
||||
}
|
||||
x509_csr;
|
||||
/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */
|
||||
/** \} addtogroup x509_module */
|
||||
|
||||
@ -300,119 +187,6 @@ x509_csr;
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Parse a single DER formatted certificate and add it
|
||||
* to the chained list.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the certificate DER data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen );
|
||||
|
||||
/**
|
||||
* \brief Parse one or more certificates and add them
|
||||
* to the chained list. Parses permissively. If some
|
||||
* certificates can be parsed, the result is the number
|
||||
* of failed certificates it encountered. If none complete
|
||||
* correctly, the first error is returned.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the certificate data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if all certificates parsed successfully, a positive number
|
||||
* if partly successful or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen );
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load one or more certificates and add them
|
||||
* to the chained list. Parses permissively. If some
|
||||
* certificates can be parsed, the result is the number
|
||||
* of failed certificates it encountered. If none complete
|
||||
* correctly, the first error is returned.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path filename to read the certificates from
|
||||
*
|
||||
* \return 0 if all certificates parsed successfully, a positive number
|
||||
* if partly successful or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crtfile( x509_cert *chain, const char *path );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load one or more certificate files from a path and add them
|
||||
* to the chained list. Parses permissively. If some
|
||||
* certificates can be parsed, the result is the number
|
||||
* of failed certificates it encountered. If none complete
|
||||
* correctly, the first error is returned.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path directory / folder to read the certificate files from
|
||||
*
|
||||
* \return 0 if all certificates parsed successfully, a positive number
|
||||
* if partly successful or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crtpath( x509_cert *chain, const char *path );
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Parse one or more CRLs and add them
|
||||
* to the chained list
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the CRL data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load a Certificate Signing Request (CSR)
|
||||
*
|
||||
* \param csr CSR context to fill
|
||||
* \param buf buffer holding the CRL data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_csr( x509_csr *csr, const unsigned char *buf, size_t buflen );
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load one or more CRLs and add them
|
||||
* to the chained list
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path filename to read the CRLs from
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crlfile( x509_crl *chain, const char *path );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Load a Certificate Signing Request (CSR)
|
||||
*
|
||||
* \param csr CSR context to fill
|
||||
* \param path filename to read the CSR from
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_csrfile( x509_csr *csr, const char *path );
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
#if defined(POLARSSL_RSA_C)
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
@ -500,51 +274,6 @@ int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn );
|
||||
*/
|
||||
int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial );
|
||||
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* certificate.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param prefix A line prefix
|
||||
* \param crt The X509 certificate to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_cert_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_cert *crt );
|
||||
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* CRL.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param prefix A line prefix
|
||||
* \param crl The X509 CRL to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_crl_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_crl *crl );
|
||||
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* CSR.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param prefix A line prefix
|
||||
* \param csr The X509 CSR to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_csr_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_csr *csr );
|
||||
|
||||
/**
|
||||
* \brief Give an known OID, return its descriptive string.
|
||||
*
|
||||
@ -579,99 +308,6 @@ int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid );
|
||||
*/
|
||||
int x509parse_time_expired( const x509_time *time );
|
||||
|
||||
/**
|
||||
* \name Functions to verify a certificate
|
||||
* \{
|
||||
*/
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Verify the certificate signature
|
||||
*
|
||||
* The verify callback is a user-supplied callback that
|
||||
* can clear / modify / add flags for a certificate. If set,
|
||||
* the verification callback is called for each
|
||||
* certificate in the chain (from the trust-ca down to the
|
||||
* presented crt). The parameters for the callback are:
|
||||
* (void *parameter, x509_cert *crt, int certificate_depth,
|
||||
* int *flags). With the flags representing current flags for
|
||||
* that specific certificate and the certificate depth from
|
||||
* the bottom (Peer cert depth = 0).
|
||||
*
|
||||
* All flags left after returning from the callback
|
||||
* are also returned to the application. The function should
|
||||
* return 0 for anything but a fatal error.
|
||||
*
|
||||
* \param crt a certificate to be verified
|
||||
* \param trust_ca the trusted CA chain
|
||||
* \param ca_crl the CRL chain for trusted CA's
|
||||
* \param cn expected Common Name (can be set to
|
||||
* NULL if the CN must not be verified)
|
||||
* \param flags result of the verification
|
||||
* \param f_vrfy verification function
|
||||
* \param p_vrfy verification parameter
|
||||
*
|
||||
* \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED,
|
||||
* in which case *flags will have one or more of
|
||||
* the following values set:
|
||||
* BADCERT_EXPIRED --
|
||||
* BADCERT_REVOKED --
|
||||
* BADCERT_CN_MISMATCH --
|
||||
* BADCERT_NOT_TRUSTED
|
||||
* or another error in case of a fatal error encountered
|
||||
* during the verification process.
|
||||
*/
|
||||
int x509parse_verify( x509_cert *crt,
|
||||
x509_cert *trust_ca,
|
||||
x509_crl *ca_crl,
|
||||
const char *cn, int *flags,
|
||||
int (*f_vrfy)(void *, x509_cert *, int, int *),
|
||||
void *p_vrfy );
|
||||
|
||||
/**
|
||||
* \brief Verify the certificate signature
|
||||
*
|
||||
* \param crt a certificate to be verified
|
||||
* \param crl the CRL to verify against
|
||||
*
|
||||
* \return 1 if the certificate is revoked, 0 otherwise
|
||||
*
|
||||
*/
|
||||
int x509parse_revoked( const x509_cert *crt, const x509_crl *crl );
|
||||
|
||||
/** \} name Functions to verify a certificate */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \name Functions to clear a certificate, CRL or private RSA key
|
||||
* \{
|
||||
*/
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Unallocate all certificate data
|
||||
*
|
||||
* \param crt Certificate chain to free
|
||||
*/
|
||||
void x509_free( x509_cert *crt );
|
||||
|
||||
/** \ingroup x509_module */
|
||||
/**
|
||||
* \brief Unallocate all CRL data
|
||||
*
|
||||
* \param crl CRL chain to free
|
||||
*/
|
||||
void x509_crl_free( x509_crl *crl );
|
||||
|
||||
/**
|
||||
* \brief Unallocate all CSR data
|
||||
*
|
||||
* \param csr CSR to free
|
||||
*/
|
||||
void x509_csr_free( x509_csr *csr );
|
||||
|
||||
/** \} name Functions to clear a certificate, CRL or private RSA key */
|
||||
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
@ -679,8 +315,32 @@ void x509_csr_free( x509_csr *csr );
|
||||
*/
|
||||
int x509_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Internal module functions
|
||||
*/
|
||||
int x509_get_name( unsigned char **p, const unsigned char *end,
|
||||
x509_name *cur );
|
||||
int x509_get_alg_null( unsigned char **p, const unsigned char *end,
|
||||
x509_buf *alg );
|
||||
int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig );
|
||||
int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
|
||||
pk_type_t *pk_alg );
|
||||
int x509_load_file( const char *path, unsigned char **buf, size_t *n );
|
||||
int x509_key_size_helper( char *buf, size_t size, const char *name );
|
||||
int x509_get_time( unsigned char **p, const unsigned char *end,
|
||||
x509_time *time );
|
||||
int x509_get_serial( unsigned char **p, const unsigned char *end,
|
||||
x509_buf *serial );
|
||||
int x509_get_ext( unsigned char **p, const unsigned char *end,
|
||||
x509_buf *ext, int tag );
|
||||
|
||||
int x509write_string_to_names( asn1_named_data **head, char *name );
|
||||
int x509_set_extension( asn1_named_data **head, const char *oid, size_t oid_len, int critical, const unsigned char *val, size_t val_len );
|
||||
int x509_write_extensions( unsigned char **p, unsigned char *start,
|
||||
asn1_named_data *first );
|
||||
int x509_write_names( unsigned char **p, unsigned char *start,
|
||||
asn1_named_data *first );
|
||||
int x509_write_sig( unsigned char **p, unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
unsigned char *sig, size_t size );
|
||||
#endif /* x509.h */
|
||||
|
151
include/polarssl/x509_crl.h
Normal file
151
include/polarssl/x509_crl.h
Normal file
@ -0,0 +1,151 @@
|
||||
/**
|
||||
* \file x509_crl.h
|
||||
*
|
||||
* \brief X.509 certificate revocation list parsing
|
||||
*
|
||||
* 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 POLARSSL_X509_CRL_H
|
||||
#define POLARSSL_X509_CRL_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "x509.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup x509_module
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* \name Structures and functions for parsing CRLs
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Certificate revocation list entry.
|
||||
* Contains the CA-specific serial numbers and revocation dates.
|
||||
*/
|
||||
typedef struct _x509_crl_entry
|
||||
{
|
||||
x509_buf raw;
|
||||
|
||||
x509_buf serial;
|
||||
|
||||
x509_time revocation_date;
|
||||
|
||||
x509_buf entry_ext;
|
||||
|
||||
struct _x509_crl_entry *next;
|
||||
}
|
||||
x509_crl_entry;
|
||||
|
||||
/**
|
||||
* Certificate revocation list structure.
|
||||
* Every CRL may have multiple entries.
|
||||
*/
|
||||
typedef struct _x509_crl
|
||||
{
|
||||
x509_buf raw; /**< The raw certificate data (DER). */
|
||||
x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
|
||||
|
||||
int version;
|
||||
x509_buf sig_oid1;
|
||||
|
||||
x509_buf issuer_raw; /**< The raw issuer data (DER). */
|
||||
|
||||
x509_name issuer; /**< The parsed issuer data (named information object). */
|
||||
|
||||
x509_time this_update;
|
||||
x509_time next_update;
|
||||
|
||||
x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */
|
||||
|
||||
x509_buf crl_ext;
|
||||
|
||||
x509_buf sig_oid2;
|
||||
x509_buf sig;
|
||||
md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */
|
||||
pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */;
|
||||
|
||||
struct _x509_crl *next;
|
||||
}
|
||||
x509_crl;
|
||||
|
||||
/**
|
||||
* \brief Parse one or more CRLs and add them
|
||||
* to the chained list
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the CRL data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen );
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/**
|
||||
* \brief Load one or more CRLs and add them
|
||||
* to the chained list
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path filename to read the CRLs from
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crlfile( x509_crl *chain, const char *path );
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* CRL.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param prefix A line prefix
|
||||
* \param crl The X509 CRL to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_crl_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_crl *crl );
|
||||
|
||||
/**
|
||||
* \brief Unallocate all CRL data
|
||||
*
|
||||
* \param crl CRL chain to free
|
||||
*/
|
||||
void x509_crl_free( x509_crl *crl );
|
||||
|
||||
/* \} name */
|
||||
/* \} addtogroup x509_module */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* x509_crl.h */
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* \file x509write.h
|
||||
* \file x509_crt.h
|
||||
*
|
||||
* \brief X509 buffer writing functionality
|
||||
* \brief X.509 certificate parsing and writing
|
||||
*
|
||||
* Copyright (C) 2006-2013, Brainspark B.V.
|
||||
*
|
||||
@ -24,30 +24,15 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_X509_WRITE_H
|
||||
#define POLARSSL_X509_WRITE_H
|
||||
#ifndef POLARSSL_X509_CRT_H
|
||||
#define POLARSSL_X509_CRT_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "x509.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
|
||||
extern "C" {
|
||||
#if defined(POLARSSL_X509_CRL_PARSE_C)
|
||||
#include "x509_crl.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -55,22 +40,61 @@ extern "C" {
|
||||
* \{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name Structures for writing X.509 CSRs (Certificate Signing Request)
|
||||
* \name Structures and functions for parsing and writing X.509 certificates
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Container for a CSR
|
||||
* Container for an X.509 certificate. The certificate may be chained.
|
||||
*/
|
||||
typedef struct _x509write_csr
|
||||
typedef struct _x509_cert
|
||||
{
|
||||
pk_context *key;
|
||||
asn1_named_data *subject;
|
||||
md_type_t md_alg;
|
||||
asn1_named_data *extensions;
|
||||
x509_buf raw; /**< The raw certificate data (DER). */
|
||||
x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
|
||||
|
||||
int version; /**< The X.509 version. (0=v1, 1=v2, 2=v3) */
|
||||
x509_buf serial; /**< Unique id for certificate issued by a specific CA. */
|
||||
x509_buf sig_oid1; /**< Signature algorithm, e.g. sha1RSA */
|
||||
|
||||
x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */
|
||||
x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */
|
||||
|
||||
x509_name issuer; /**< The parsed issuer data (named information object). */
|
||||
x509_name subject; /**< The parsed subject data (named information object). */
|
||||
|
||||
x509_time valid_from; /**< Start time of certificate validity. */
|
||||
x509_time valid_to; /**< End time of certificate validity. */
|
||||
|
||||
pk_context pk; /**< Container for the public key context. */
|
||||
|
||||
x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
|
||||
x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
|
||||
x509_buf v3_ext; /**< Optional X.509 v3 extensions. Only Basic Contraints are supported at this time. */
|
||||
x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */
|
||||
|
||||
int ext_types; /**< Bit string containing detected and parsed extensions */
|
||||
int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
|
||||
int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */
|
||||
|
||||
unsigned char key_usage; /**< Optional key usage extension value: See the values below */
|
||||
|
||||
x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
|
||||
|
||||
unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values below */
|
||||
|
||||
x509_buf sig_oid2; /**< Signature algorithm. Must match sig_oid1. */
|
||||
x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */
|
||||
md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */
|
||||
pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */;
|
||||
|
||||
struct _x509_cert *next; /**< Next certificate in the CA-chain. */
|
||||
}
|
||||
x509write_csr;
|
||||
x509_cert;
|
||||
|
||||
#define X509_CRT_VERSION_1 0
|
||||
#define X509_CRT_VERSION_2 1
|
||||
@ -97,93 +121,151 @@ typedef struct _x509write_cert
|
||||
}
|
||||
x509write_cert;
|
||||
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
/**
|
||||
* \brief Parse a single DER formatted certificate and add it
|
||||
* to the chained list.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the certificate DER data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crt_der( x509_cert *chain, const unsigned char *buf,
|
||||
size_t buflen );
|
||||
|
||||
/**
|
||||
* \brief Parse one or more certificates and add them
|
||||
* to the chained list. Parses permissively. If some
|
||||
* certificates can be parsed, the result is the number
|
||||
* of failed certificates it encountered. If none complete
|
||||
* correctly, the first error is returned.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the certificate data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if all certificates parsed successfully, a positive number
|
||||
* if partly successful or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen );
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/**
|
||||
* \brief Load one or more certificates and add them
|
||||
* to the chained list. Parses permissively. If some
|
||||
* certificates can be parsed, the result is the number
|
||||
* of failed certificates it encountered. If none complete
|
||||
* correctly, the first error is returned.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path filename to read the certificates from
|
||||
*
|
||||
* \return 0 if all certificates parsed successfully, a positive number
|
||||
* if partly successful or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crtfile( x509_cert *chain, const char *path );
|
||||
|
||||
/**
|
||||
* \brief Load one or more certificate files from a path and add them
|
||||
* to the chained list. Parses permissively. If some
|
||||
* certificates can be parsed, the result is the number
|
||||
* of failed certificates it encountered. If none complete
|
||||
* correctly, the first error is returned.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param path directory / folder to read the certificate files from
|
||||
*
|
||||
* \return 0 if all certificates parsed successfully, a positive number
|
||||
* if partly successful or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_crtpath( x509_cert *chain, const char *path );
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* certificate.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param prefix A line prefix
|
||||
* \param crt The X509 certificate to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_cert_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_cert *crt );
|
||||
|
||||
/**
|
||||
* \brief Verify the certificate signature
|
||||
*
|
||||
* The verify callback is a user-supplied callback that
|
||||
* can clear / modify / add flags for a certificate. If set,
|
||||
* the verification callback is called for each
|
||||
* certificate in the chain (from the trust-ca down to the
|
||||
* presented crt). The parameters for the callback are:
|
||||
* (void *parameter, x509_cert *crt, int certificate_depth,
|
||||
* int *flags). With the flags representing current flags for
|
||||
* that specific certificate and the certificate depth from
|
||||
* the bottom (Peer cert depth = 0).
|
||||
*
|
||||
* All flags left after returning from the callback
|
||||
* are also returned to the application. The function should
|
||||
* return 0 for anything but a fatal error.
|
||||
*
|
||||
* \param crt a certificate to be verified
|
||||
* \param trust_ca the trusted CA chain
|
||||
* \param ca_crl the CRL chain for trusted CA's
|
||||
* \param cn expected Common Name (can be set to
|
||||
* NULL if the CN must not be verified)
|
||||
* \param flags result of the verification
|
||||
* \param f_vrfy verification function
|
||||
* \param p_vrfy verification parameter
|
||||
*
|
||||
* \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED,
|
||||
* in which case *flags will have one or more of
|
||||
* the following values set:
|
||||
* BADCERT_EXPIRED --
|
||||
* BADCERT_REVOKED --
|
||||
* BADCERT_CN_MISMATCH --
|
||||
* BADCERT_NOT_TRUSTED
|
||||
* or another error in case of a fatal error encountered
|
||||
* during the verification process.
|
||||
*/
|
||||
int x509parse_verify( x509_cert *crt,
|
||||
x509_cert *trust_ca,
|
||||
x509_crl *ca_crl,
|
||||
const char *cn, int *flags,
|
||||
int (*f_vrfy)(void *, x509_cert *, int, int *),
|
||||
void *p_vrfy );
|
||||
|
||||
#if defined(POLARSSL_X509_CRL_PARSE_C)
|
||||
/**
|
||||
* \brief Verify the certificate signature
|
||||
*
|
||||
* \param crt a certificate to be verified
|
||||
* \param crl the CRL to verify against
|
||||
*
|
||||
* \return 1 if the certificate is revoked, 0 otherwise
|
||||
*
|
||||
*/
|
||||
int x509parse_revoked( const x509_cert *crt, const x509_crl *crl );
|
||||
#endif /* POLARSSL_X509_CRL_PARSE_C */
|
||||
|
||||
/**
|
||||
* \brief Unallocate all certificate data
|
||||
*
|
||||
* \param crt Certificate chain to free
|
||||
*/
|
||||
void x509_crt_free( x509_cert *crt );
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
/* \} name */
|
||||
/* \} addtogroup x509_module */
|
||||
|
||||
/**
|
||||
* \brief Initialize a CSR context
|
||||
*
|
||||
* \param ctx CSR context to initialize
|
||||
*/
|
||||
void x509write_csr_init( x509write_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( x509write_csr *ctx, char *subject_name );
|
||||
|
||||
/**
|
||||
* \brief Set the 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 key Asymetric key to include
|
||||
*/
|
||||
void x509write_csr_set_key( x509write_csr *ctx, pk_context *key );
|
||||
|
||||
/**
|
||||
* \brief Set the MD algorithm to use for the signature
|
||||
* (e.g. POLARSSL_MD_SHA1)
|
||||
*
|
||||
* \param ctx CSR context to use
|
||||
* \param md_alg MD algorithm to use
|
||||
*/
|
||||
void x509write_csr_set_md_alg( x509write_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( x509write_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( x509write_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( x509write_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( x509write_csr *ctx );
|
||||
|
||||
#if defined(POLARSSL_X509_CRT_WRITE_C)
|
||||
/**
|
||||
* \brief Initialize a CRT writing context
|
||||
*
|
||||
@ -389,31 +471,6 @@ int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \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 ctx CSR to write away
|
||||
* \param buf buffer to write to
|
||||
* \param size size of the buffer
|
||||
* \param f_rng RNG function (for signature, see note)
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return length of data written if successful, or a specific
|
||||
* error code
|
||||
*
|
||||
* \note f_rng may be NULL if RSA is used for signature and the
|
||||
* signature is made offline (otherwise f_rng is desirable
|
||||
* for countermeasures against timing attacks).
|
||||
* ECDSA signatures always require a non-NULL f_rng.
|
||||
*/
|
||||
int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
#if defined(POLARSSL_PEM_WRITE_C)
|
||||
/**
|
||||
* \brief Write a built up certificate to a X509 PEM string
|
||||
@ -434,31 +491,11 @@ int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size,
|
||||
int x509write_crt_pem( x509write_cert *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief Write a CSR (Certificate Signing Request) to a
|
||||
* PEM string
|
||||
*
|
||||
* \param ctx CSR to write away
|
||||
* \param buf buffer to write to
|
||||
* \param size size of the buffer
|
||||
* \param f_rng RNG function (for signature, see note)
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return 0 successful, or a specific error code
|
||||
*
|
||||
* \note f_rng may be NULL if RSA is used for signature and the
|
||||
* signature is made offline (otherwise f_rng is desirable
|
||||
* for couermeasures against timing attacks).
|
||||
* ECDSA signatures always require a non-NULL f_rng.
|
||||
*/
|
||||
int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
#endif /* POLARSSL_PEM_WRITE_C */
|
||||
#endif /* POLARSSL_X509_CRT_WRITE_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* POLARSSL_X509_WRITE_H */
|
||||
#endif /* x509_crt.h */
|
269
include/polarssl/x509_csr.h
Normal file
269
include/polarssl/x509_csr.h
Normal file
@ -0,0 +1,269 @@
|
||||
/**
|
||||
* \file x509_csr.h
|
||||
*
|
||||
* \brief X.509 certificate signing request parsing and writing
|
||||
*
|
||||
* 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 POLARSSL_X509_CSR_H
|
||||
#define POLARSSL_X509_CSR_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "x509.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup x509_module
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* \name Structures and functions for X.509 Certificate Signing Requests (CSR)
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Certificate Signing Request (CSR) structure.
|
||||
*/
|
||||
typedef struct _x509_csr
|
||||
{
|
||||
x509_buf raw; /**< The raw CSR data (DER). */
|
||||
x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */
|
||||
|
||||
int version;
|
||||
|
||||
x509_buf subject_raw; /**< The raw subject data (DER). */
|
||||
x509_name subject; /**< The parsed subject data (named information object). */
|
||||
|
||||
pk_context pk; /**< Container for the public key context. */
|
||||
|
||||
x509_buf sig_oid;
|
||||
x509_buf sig;
|
||||
md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */
|
||||
pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */;
|
||||
}
|
||||
x509_csr;
|
||||
|
||||
/**
|
||||
* Container for writing a CSR
|
||||
*/
|
||||
typedef struct _x509write_csr
|
||||
{
|
||||
pk_context *key;
|
||||
asn1_named_data *subject;
|
||||
md_type_t md_alg;
|
||||
asn1_named_data *extensions;
|
||||
}
|
||||
x509write_csr;
|
||||
|
||||
#if defined(POLARSSL_X509_CSR_PARSE_C)
|
||||
/**
|
||||
* \brief Load a Certificate Signing Request (CSR)
|
||||
*
|
||||
* \param csr CSR context to fill
|
||||
* \param buf buffer holding the CRL data
|
||||
* \param buflen size of the buffer
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_csr( x509_csr *csr, const unsigned char *buf, size_t buflen );
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/**
|
||||
* \brief Load a Certificate Signing Request (CSR)
|
||||
*
|
||||
* \param csr CSR context to fill
|
||||
* \param path filename to read the CSR from
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 or PEM error code
|
||||
*/
|
||||
int x509parse_csrfile( x509_csr *csr, const char *path );
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
* CSR.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param prefix A line prefix
|
||||
* \param csr The X509 CSR to represent
|
||||
*
|
||||
* \return The amount of data written to the buffer, or -1 in
|
||||
* case of an error.
|
||||
*/
|
||||
int x509parse_csr_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_csr *csr );
|
||||
|
||||
/**
|
||||
* \brief Unallocate all CSR data
|
||||
*
|
||||
* \param csr CSR to free
|
||||
*/
|
||||
void x509_csr_free( x509_csr *csr );
|
||||
#endif /* POLARSSL_X509_CSR_PARSE_C */
|
||||
|
||||
/* \} name */
|
||||
/* \} addtogroup x509_module */
|
||||
|
||||
#if defined(POLARSSL_X509_CSR_WRITE_C)
|
||||
/**
|
||||
* \brief Initialize a CSR context
|
||||
*
|
||||
* \param ctx CSR context to initialize
|
||||
*/
|
||||
void x509write_csr_init( x509write_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( x509write_csr *ctx, char *subject_name );
|
||||
|
||||
/**
|
||||
* \brief Set the 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 key Asymetric key to include
|
||||
*/
|
||||
void x509write_csr_set_key( x509write_csr *ctx, pk_context *key );
|
||||
|
||||
/**
|
||||
* \brief Set the MD algorithm to use for the signature
|
||||
* (e.g. POLARSSL_MD_SHA1)
|
||||
*
|
||||
* \param ctx CSR context to use
|
||||
* \param md_alg MD algorithm to use
|
||||
*/
|
||||
void x509write_csr_set_md_alg( x509write_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( x509write_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( x509write_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( x509write_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( x509write_csr *ctx );
|
||||
|
||||
/**
|
||||
* \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 ctx CSR to write away
|
||||
* \param buf buffer to write to
|
||||
* \param size size of the buffer
|
||||
* \param f_rng RNG function (for signature, see note)
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return length of data written if successful, or a specific
|
||||
* error code
|
||||
*
|
||||
* \note f_rng may be NULL if RSA is used for signature and the
|
||||
* signature is made offline (otherwise f_rng is desirable
|
||||
* for countermeasures against timing attacks).
|
||||
* ECDSA signatures always require a non-NULL f_rng.
|
||||
*/
|
||||
int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
#if defined(POLARSSL_PEM_WRITE_C)
|
||||
/**
|
||||
* \brief Write a CSR (Certificate Signing Request) to a
|
||||
* PEM string
|
||||
*
|
||||
* \param ctx CSR to write away
|
||||
* \param buf buffer to write to
|
||||
* \param size size of the buffer
|
||||
* \param f_rng RNG function (for signature, see note)
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return 0 successful, or a specific error code
|
||||
*
|
||||
* \note f_rng may be NULL if RSA is used for signature and the
|
||||
* signature is made offline (otherwise f_rng is desirable
|
||||
* for couermeasures against timing attacks).
|
||||
* ECDSA signatures always require a non-NULL f_rng.
|
||||
*/
|
||||
int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
#endif /* POLARSSL_PEM_WRITE_C */
|
||||
#endif /* POLARSSL_X509_CSR_WRITE_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* x509_csr.h */
|
@ -49,13 +49,18 @@ set(src
|
||||
sha512.c
|
||||
ssl_cache.c
|
||||
ssl_ciphersuites.c
|
||||
ssl_cli.c
|
||||
ssl_srv.c
|
||||
ssl_cli.c
|
||||
ssl_srv.c
|
||||
ssl_tls.c
|
||||
timing.c
|
||||
version.c
|
||||
x509parse.c
|
||||
x509write.c
|
||||
x509.c
|
||||
x509_crt.c
|
||||
x509_crl.c
|
||||
x509_csr.c
|
||||
x509_create.c
|
||||
x509_crt_write.c
|
||||
x509_csr_write.c
|
||||
xtea.c
|
||||
)
|
||||
|
||||
|
@ -224,7 +224,7 @@ void debug_print_mpi( const ssl_context *ssl, int level,
|
||||
}
|
||||
#endif /* POLARSSL_BIGNUM_C */
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
static void debug_print_pk( const ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const pk_context *pk )
|
||||
@ -288,6 +288,6 @@ void debug_print_crt( const ssl_context *ssl, int level,
|
||||
crt = crt->next;
|
||||
}
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "polarssl/oid.h"
|
||||
#include "polarssl/rsa.h"
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C) || defined(POLARSSL_X509_WRITE_C)
|
||||
#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
|
||||
#include "polarssl/x509.h"
|
||||
#endif
|
||||
|
||||
@ -207,7 +207,7 @@ static const oid_x520_attr_t oid_x520_attr_type[] =
|
||||
FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type);
|
||||
FN_OID_GET_ATTR1(oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name);
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C) || defined(POLARSSL_X509_WRITE_C)
|
||||
#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
|
||||
/*
|
||||
* For X509 extensions
|
||||
*/
|
||||
@ -260,7 +260,7 @@ static const oid_descriptor_t oid_ext_key_usage[] =
|
||||
|
||||
FN_OID_TYPED_FROM_ASN1(oid_descriptor_t, ext_key_usage, oid_ext_key_usage);
|
||||
FN_OID_GET_ATTR1(oid_get_extended_key_usage, oid_descriptor_t, ext_key_usage, const char *, description);
|
||||
#endif /* POLARSSL_X509_PARSE_C || POLARSSL_X509_WRITE_C */
|
||||
#endif /* POLARSSL_X509_USE_C || POLARSSL_X509_CREATE_C */
|
||||
|
||||
#if defined(POLARSSL_MD_C)
|
||||
/*
|
||||
|
@ -85,7 +85,7 @@ int ssl_cache_get( void *data, ssl_session *session )
|
||||
|
||||
session->verify_result = entry->session.verify_result;
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
/*
|
||||
* Restore peer certificate (without rest of the original chain)
|
||||
*/
|
||||
@ -104,7 +104,7 @@ int ssl_cache_get( void *data, ssl_session *session )
|
||||
return( 1 );
|
||||
}
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -163,13 +163,13 @@ int ssl_cache_set( void *data, const ssl_session *session )
|
||||
{
|
||||
cur = old;
|
||||
memset( &cur->session, 0, sizeof(ssl_session) );
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
if( cur->peer_cert.p != NULL )
|
||||
{
|
||||
polarssl_free( cur->peer_cert.p );
|
||||
memset( &cur->peer_cert, 0, sizeof(x509_buf) );
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
}
|
||||
#else /* POLARSSL_HAVE_TIME */
|
||||
/*
|
||||
@ -184,13 +184,13 @@ int ssl_cache_set( void *data, const ssl_session *session )
|
||||
cur = cache->chain;
|
||||
cache->chain = cur->next;
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
if( cur->peer_cert.p != NULL )
|
||||
{
|
||||
polarssl_free( cur->peer_cert.p );
|
||||
memset( &cur->peer_cert, 0, sizeof(x509_buf) );
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
memset( cur, 0, sizeof(ssl_cache_entry) );
|
||||
prv->next = cur;
|
||||
@ -217,7 +217,7 @@ int ssl_cache_set( void *data, const ssl_session *session )
|
||||
|
||||
memcpy( &cur->session, session, sizeof( ssl_session ) );
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
/*
|
||||
* Store peer certificate
|
||||
*/
|
||||
@ -233,7 +233,7 @@ int ssl_cache_set( void *data, const ssl_session *session )
|
||||
|
||||
cur->session.peer_cert = NULL;
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -267,10 +267,10 @@ void ssl_cache_free( ssl_cache_context *cache )
|
||||
|
||||
ssl_session_free( &prv->session );
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
if( prv->peer_cert.p != NULL )
|
||||
polarssl_free( prv->peer_cert.p );
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
polarssl_free( prv );
|
||||
}
|
||||
|
@ -62,9 +62,9 @@ static int ssl_save_session( const ssl_session *session,
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
size_t left = buf_len;
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
size_t cert_len;
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
if( left < sizeof( ssl_session ) )
|
||||
return( -1 );
|
||||
@ -73,7 +73,7 @@ static int ssl_save_session( const ssl_session *session,
|
||||
p += sizeof( ssl_session );
|
||||
left -= sizeof( ssl_session );
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
((ssl_session *) buf)->peer_cert = NULL;
|
||||
|
||||
if( session->peer_cert == NULL )
|
||||
@ -92,7 +92,7 @@ static int ssl_save_session( const ssl_session *session,
|
||||
memcpy( p, session->peer_cert->raw.p, cert_len );
|
||||
|
||||
p += cert_len;
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
*olen = p - buf;
|
||||
|
||||
@ -107,9 +107,9 @@ static int ssl_load_session( ssl_session *session,
|
||||
{
|
||||
const unsigned char *p = buf;
|
||||
const unsigned char * const end = buf + len;
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
size_t cert_len;
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
if( p + sizeof( ssl_session ) > end )
|
||||
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
|
||||
@ -117,7 +117,7 @@ static int ssl_load_session( ssl_session *session,
|
||||
memcpy( session, p, sizeof( ssl_session ) );
|
||||
p += sizeof( ssl_session );
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
if( p + 3 > end )
|
||||
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
|
||||
|
||||
@ -144,7 +144,7 @@ static int ssl_load_session( ssl_session *session,
|
||||
|
||||
if( ( ret = x509parse_crt( session->peer_cert, p, cert_len ) ) != 0 )
|
||||
{
|
||||
x509_free( session->peer_cert );
|
||||
x509_crt_free( session->peer_cert );
|
||||
polarssl_free( session->peer_cert );
|
||||
session->peer_cert = NULL;
|
||||
return( ret );
|
||||
@ -152,7 +152,7 @@ static int ssl_load_session( ssl_session *session,
|
||||
|
||||
p += cert_len;
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
if( p != end )
|
||||
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
|
||||
|
@ -75,7 +75,7 @@ static int ssl_session_copy( ssl_session *dst, const ssl_session *src )
|
||||
ssl_session_free( dst );
|
||||
memcpy( dst, src, sizeof( ssl_session ) );
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
if( src->peer_cert != NULL )
|
||||
{
|
||||
int ret;
|
||||
@ -93,7 +93,7 @@ static int ssl_session_copy( ssl_session *dst, const ssl_session *src )
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
#if defined(POLARSSL_SSL_SESSION_TICKETS)
|
||||
if( src->ticket != NULL )
|
||||
@ -2482,7 +2482,7 @@ int ssl_parse_certificate( ssl_context *ssl )
|
||||
/* In case we tried to reuse a session but it failed */
|
||||
if( ssl->session_negotiate->peer_cert != NULL )
|
||||
{
|
||||
x509_free( ssl->session_negotiate->peer_cert );
|
||||
x509_crt_free( ssl->session_negotiate->peer_cert );
|
||||
polarssl_free( ssl->session_negotiate->peer_cert );
|
||||
}
|
||||
|
||||
@ -3377,7 +3377,7 @@ void ssl_set_authmode( ssl_context *ssl, int authmode )
|
||||
ssl->authmode = authmode;
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
void ssl_set_verify( ssl_context *ssl,
|
||||
int (*f_vrfy)(void *, x509_cert *, int, int *),
|
||||
void *p_vrfy )
|
||||
@ -3385,7 +3385,7 @@ void ssl_set_verify( ssl_context *ssl,
|
||||
ssl->f_vrfy = f_vrfy;
|
||||
ssl->p_vrfy = p_vrfy;
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
void ssl_set_rng( ssl_context *ssl,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
@ -3463,7 +3463,7 @@ void ssl_set_ciphersuites_for_version( ssl_context *ssl, const int *ciphersuites
|
||||
ssl->ciphersuite_list[minor] = ciphersuites;
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
void ssl_set_ca_chain( ssl_context *ssl, x509_cert *ca_chain,
|
||||
x509_crl *ca_crl, const char *peer_cn )
|
||||
{
|
||||
@ -3523,7 +3523,7 @@ int ssl_set_own_cert_alt( ssl_context *ssl, x509_cert *own_cert,
|
||||
return( pk_init_ctx_rsa_alt( ssl->pk_key, rsa_key,
|
||||
rsa_decrypt, rsa_sign, rsa_key_len ) );
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
|
||||
void ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len,
|
||||
@ -3730,7 +3730,7 @@ const char *ssl_get_version( const ssl_context *ssl )
|
||||
return( "unknown" );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
const x509_cert *ssl_get_peer_cert( const ssl_context *ssl )
|
||||
{
|
||||
if( ssl == NULL || ssl->session == NULL )
|
||||
@ -3738,7 +3738,7 @@ const x509_cert *ssl_get_peer_cert( const ssl_context *ssl )
|
||||
|
||||
return ssl->session->peer_cert;
|
||||
}
|
||||
#endif /* POLARSSL_X509_PARSE_C */
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
int ssl_get_session( const ssl_context *ssl, ssl_session *dst )
|
||||
{
|
||||
@ -4076,10 +4076,10 @@ void ssl_handshake_free( ssl_handshake_params *handshake )
|
||||
|
||||
void ssl_session_free( ssl_session *session )
|
||||
{
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||
if( session->peer_cert != NULL )
|
||||
{
|
||||
x509_free( session->peer_cert );
|
||||
x509_crt_free( session->peer_cert );
|
||||
polarssl_free( session->peer_cert );
|
||||
}
|
||||
#endif
|
||||
|
798
library/x509.c
Normal file
798
library/x509.c
Normal file
@ -0,0 +1,798 @@
|
||||
/*
|
||||
* X.509 certificate and private key decoding
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* The ITU-T X.509 standard defines a certificate format for PKI.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc3279.txt
|
||||
* http://www.ietf.org/rfc/rfc3280.txt
|
||||
*
|
||||
* ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
|
||||
*
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_X509_USE_C)
|
||||
|
||||
#include "polarssl/x509.h"
|
||||
#include "polarssl/asn1.h"
|
||||
#include "polarssl/oid.h"
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
#include "polarssl/pem.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MEMORY_C)
|
||||
#include "polarssl/memory.h"
|
||||
#else
|
||||
#define polarssl_malloc malloc
|
||||
#define polarssl_free free
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
#include <stdio.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CertificateSerialNumber ::= INTEGER
|
||||
*/
|
||||
int x509_get_serial( unsigned char **p, const unsigned char *end,
|
||||
x509_buf *serial )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ( end - *p ) < 1 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
|
||||
POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
|
||||
**p != ASN1_INTEGER )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
|
||||
POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
|
||||
|
||||
serial->tag = *(*p)++;
|
||||
|
||||
if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
|
||||
|
||||
serial->p = *p;
|
||||
*p += serial->len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Get an algorithm identifier without parameters (eg for signatures)
|
||||
*
|
||||
* AlgorithmIdentifier ::= SEQUENCE {
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm OPTIONAL }
|
||||
*/
|
||||
int x509_get_alg_null( unsigned char **p, const unsigned char *end,
|
||||
x509_buf *alg )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
*/
|
||||
static int x509_get_attr_type_value( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
x509_name *cur )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
x509_buf *oid;
|
||||
x509_buf *val;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
|
||||
|
||||
if( ( end - *p ) < 1 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
|
||||
POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
oid = &cur->oid;
|
||||
oid->tag = **p;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
|
||||
|
||||
oid->p = *p;
|
||||
*p += oid->len;
|
||||
|
||||
if( ( end - *p ) < 1 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
|
||||
POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
|
||||
**p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
|
||||
**p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
|
||||
POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
|
||||
|
||||
val = &cur->val;
|
||||
val->tag = *(*p)++;
|
||||
|
||||
if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
|
||||
|
||||
val->p = *p;
|
||||
*p += val->len;
|
||||
|
||||
cur->next = NULL;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* RelativeDistinguishedName ::=
|
||||
* SET OF AttributeTypeAndValue
|
||||
*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
*/
|
||||
int x509_get_name( unsigned char **p, const unsigned char *end,
|
||||
x509_name *cur )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
const unsigned char *end2;
|
||||
x509_name *use;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
|
||||
|
||||
end2 = end;
|
||||
end = *p + len;
|
||||
use = cur;
|
||||
|
||||
do
|
||||
{
|
||||
if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( *p != end )
|
||||
{
|
||||
use->next = (x509_name *) polarssl_malloc(
|
||||
sizeof( x509_name ) );
|
||||
|
||||
if( use->next == NULL )
|
||||
return( POLARSSL_ERR_X509_MALLOC_FAILED );
|
||||
|
||||
memset( use->next, 0, sizeof( x509_name ) );
|
||||
|
||||
use = use->next;
|
||||
}
|
||||
}
|
||||
while( *p != end );
|
||||
|
||||
/*
|
||||
* recurse until end of SEQUENCE is reached
|
||||
*/
|
||||
if( *p == end2 )
|
||||
return( 0 );
|
||||
|
||||
cur->next = (x509_name *) polarssl_malloc(
|
||||
sizeof( x509_name ) );
|
||||
|
||||
if( cur->next == NULL )
|
||||
return( POLARSSL_ERR_X509_MALLOC_FAILED );
|
||||
|
||||
memset( cur->next, 0, sizeof( x509_name ) );
|
||||
|
||||
return( x509_get_name( p, end2, cur->next ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Time ::= CHOICE {
|
||||
* utcTime UTCTime,
|
||||
* generalTime GeneralizedTime }
|
||||
*/
|
||||
int x509_get_time( unsigned char **p, const unsigned char *end,
|
||||
x509_time *time )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
char date[64];
|
||||
unsigned char tag;
|
||||
|
||||
if( ( end - *p ) < 1 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
|
||||
POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
tag = **p;
|
||||
|
||||
if ( tag == ASN1_UTC_TIME )
|
||||
{
|
||||
(*p)++;
|
||||
ret = asn1_get_len( p, end, &len );
|
||||
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
|
||||
|
||||
memset( date, 0, sizeof( date ) );
|
||||
memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
|
||||
len : sizeof( date ) - 1 );
|
||||
|
||||
if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
|
||||
&time->year, &time->mon, &time->day,
|
||||
&time->hour, &time->min, &time->sec ) < 5 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
|
||||
|
||||
time->year += 100 * ( time->year < 50 );
|
||||
time->year += 1900;
|
||||
|
||||
*p += len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
else if ( tag == ASN1_GENERALIZED_TIME )
|
||||
{
|
||||
(*p)++;
|
||||
ret = asn1_get_len( p, end, &len );
|
||||
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
|
||||
|
||||
memset( date, 0, sizeof( date ) );
|
||||
memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
|
||||
len : sizeof( date ) - 1 );
|
||||
|
||||
if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
|
||||
&time->year, &time->mon, &time->day,
|
||||
&time->hour, &time->min, &time->sec ) < 5 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
|
||||
|
||||
*p += len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
else
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
|
||||
}
|
||||
|
||||
int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
if( ( end - *p ) < 1 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +
|
||||
POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
sig->tag = **p;
|
||||
|
||||
if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
|
||||
|
||||
sig->len = len;
|
||||
sig->p = *p;
|
||||
|
||||
*p += len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
|
||||
pk_type_t *pk_alg )
|
||||
{
|
||||
int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
|
||||
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* X.509 Extensions (No parsing of extensions, pointer should
|
||||
* be either manually updated or extensions should be parsed!
|
||||
*/
|
||||
int x509_get_ext( unsigned char **p, const unsigned char *end,
|
||||
x509_buf *ext, int tag )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
if( *p == end )
|
||||
return( 0 );
|
||||
|
||||
ext->tag = **p;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &ext->len,
|
||||
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
ext->p = *p;
|
||||
end = *p + ext->len;
|
||||
|
||||
/*
|
||||
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
|
||||
*
|
||||
* Extension ::= SEQUENCE {
|
||||
* extnID OBJECT IDENTIFIER,
|
||||
* critical BOOLEAN DEFAULT FALSE,
|
||||
* extnValue OCTET STRING }
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
|
||||
|
||||
if( end != *p + len )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/*
|
||||
* Load all data from a file into a given buffer.
|
||||
*/
|
||||
int x509_load_file( const char *path, unsigned char **buf, size_t *n )
|
||||
{
|
||||
FILE *f;
|
||||
long size;
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( POLARSSL_ERR_X509_FILE_IO_ERROR );
|
||||
|
||||
fseek( f, 0, SEEK_END );
|
||||
if( ( size = ftell( f ) ) == -1 )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_X509_FILE_IO_ERROR );
|
||||
}
|
||||
fseek( f, 0, SEEK_SET );
|
||||
|
||||
*n = (size_t) size;
|
||||
|
||||
if( *n + 1 == 0 ||
|
||||
( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
|
||||
{
|
||||
fclose( f );
|
||||
return( POLARSSL_ERR_X509_MALLOC_FAILED );
|
||||
}
|
||||
|
||||
if( fread( *buf, 1, *n, f ) != *n )
|
||||
{
|
||||
fclose( f );
|
||||
polarssl_free( *buf );
|
||||
return( POLARSSL_ERR_X509_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
|
||||
(*buf)[*n] = '\0';
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_RSA_C)
|
||||
/*
|
||||
* Load and parse a private RSA key
|
||||
*/
|
||||
int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd )
|
||||
{
|
||||
int ret;
|
||||
pk_context pk;
|
||||
|
||||
pk_init( &pk );
|
||||
|
||||
ret = pk_parse_keyfile( &pk, path, pwd );
|
||||
|
||||
if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) )
|
||||
ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
|
||||
|
||||
if( ret == 0 )
|
||||
rsa_copy( rsa, pk_rsa( pk ) );
|
||||
else
|
||||
rsa_free( rsa );
|
||||
|
||||
pk_free( &pk );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Load and parse a public RSA key
|
||||
*/
|
||||
int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path )
|
||||
{
|
||||
int ret;
|
||||
pk_context pk;
|
||||
|
||||
pk_init( &pk );
|
||||
|
||||
ret = pk_parse_public_keyfile( &pk, path );
|
||||
|
||||
if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) )
|
||||
ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
|
||||
|
||||
if( ret == 0 )
|
||||
rsa_copy( rsa, pk_rsa( pk ) );
|
||||
else
|
||||
rsa_free( rsa );
|
||||
|
||||
pk_free( &pk );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* POLARSSL_RSA_C */
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
#if defined(POLARSSL_RSA_C)
|
||||
/*
|
||||
* Parse a private RSA key
|
||||
*/
|
||||
int x509parse_key_rsa( rsa_context *rsa,
|
||||
const unsigned char *key, size_t keylen,
|
||||
const unsigned char *pwd, size_t pwdlen )
|
||||
{
|
||||
int ret;
|
||||
pk_context pk;
|
||||
|
||||
pk_init( &pk );
|
||||
|
||||
ret = pk_parse_key( &pk, key, keylen, pwd, pwdlen );
|
||||
|
||||
if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) )
|
||||
ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
|
||||
|
||||
if( ret == 0 )
|
||||
rsa_copy( rsa, pk_rsa( pk ) );
|
||||
else
|
||||
rsa_free( rsa );
|
||||
|
||||
pk_free( &pk );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a public RSA key
|
||||
*/
|
||||
int x509parse_public_key_rsa( rsa_context *rsa,
|
||||
const unsigned char *key, size_t keylen )
|
||||
{
|
||||
int ret;
|
||||
pk_context pk;
|
||||
|
||||
pk_init( &pk );
|
||||
|
||||
ret = pk_parse_public_key( &pk, key, keylen );
|
||||
|
||||
if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) )
|
||||
ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
|
||||
|
||||
if( ret == 0 )
|
||||
rsa_copy( rsa, pk_rsa( pk ) );
|
||||
else
|
||||
rsa_free( rsa );
|
||||
|
||||
pk_free( &pk );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* POLARSSL_RSA_C */
|
||||
|
||||
#if defined _MSC_VER && !defined snprintf
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined vsnprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif // vsnprintf
|
||||
|
||||
/*
|
||||
* Windows _snprintf and _vsnprintf are not compatible to linux versions.
|
||||
* Result value is not size of buffer needed, but -1 if no fit is possible.
|
||||
*
|
||||
* This fuction tries to 'fix' this by at least suggesting enlarging the
|
||||
* size by 20.
|
||||
*/
|
||||
static int compat_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int res = -1;
|
||||
|
||||
va_start( ap, format );
|
||||
|
||||
res = vsnprintf( str, size, format, ap );
|
||||
|
||||
va_end( ap );
|
||||
|
||||
// No quick fix possible
|
||||
if ( res < 0 )
|
||||
return( (int) size + 20 );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define snprintf compat_snprintf
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
|
||||
|
||||
#define SAFE_SNPRINTF() \
|
||||
{ \
|
||||
if( ret == -1 ) \
|
||||
return( -1 ); \
|
||||
\
|
||||
if ( (unsigned int) ret > n ) { \
|
||||
p[n - 1] = '\0'; \
|
||||
return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
|
||||
} \
|
||||
\
|
||||
n -= (unsigned int) ret; \
|
||||
p += (unsigned int) ret; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the name in printable form into buf; no more
|
||||
* than size characters will be written
|
||||
*/
|
||||
int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
|
||||
{
|
||||
int ret;
|
||||
size_t i, n;
|
||||
unsigned char c;
|
||||
const x509_name *name;
|
||||
const char *short_name = NULL;
|
||||
char s[128], *p;
|
||||
|
||||
memset( s, 0, sizeof( s ) );
|
||||
|
||||
name = dn;
|
||||
p = buf;
|
||||
n = size;
|
||||
|
||||
while( name != NULL )
|
||||
{
|
||||
if( !name->oid.p )
|
||||
{
|
||||
name = name->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( name != dn )
|
||||
{
|
||||
ret = snprintf( p, n, ", " );
|
||||
SAFE_SNPRINTF();
|
||||
}
|
||||
|
||||
ret = oid_get_attr_short_name( &name->oid, &short_name );
|
||||
|
||||
if( ret == 0 )
|
||||
ret = snprintf( p, n, "%s=", short_name );
|
||||
else
|
||||
ret = snprintf( p, n, "\?\?=" );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
for( i = 0; i < name->val.len; i++ )
|
||||
{
|
||||
if( i >= sizeof( s ) - 1 )
|
||||
break;
|
||||
|
||||
c = name->val.p[i];
|
||||
if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
|
||||
s[i] = '?';
|
||||
else s[i] = c;
|
||||
}
|
||||
s[i] = '\0';
|
||||
ret = snprintf( p, n, "%s", s );
|
||||
SAFE_SNPRINTF();
|
||||
name = name->next;
|
||||
}
|
||||
|
||||
return( (int) ( size - n ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the serial in printable form into buf; no more
|
||||
* than size characters will be written
|
||||
*/
|
||||
int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
|
||||
{
|
||||
int ret;
|
||||
size_t i, n, nr;
|
||||
char *p;
|
||||
|
||||
p = buf;
|
||||
n = size;
|
||||
|
||||
nr = ( serial->len <= 32 )
|
||||
? serial->len : 28;
|
||||
|
||||
for( i = 0; i < nr; i++ )
|
||||
{
|
||||
if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
|
||||
continue;
|
||||
|
||||
ret = snprintf( p, n, "%02X%s",
|
||||
serial->p[i], ( i < nr - 1 ) ? ":" : "" );
|
||||
SAFE_SNPRINTF();
|
||||
}
|
||||
|
||||
if( nr != serial->len )
|
||||
{
|
||||
ret = snprintf( p, n, "...." );
|
||||
SAFE_SNPRINTF();
|
||||
}
|
||||
|
||||
return( (int) ( size - n ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper for writing "RSA key size", "EC key size", etc
|
||||
*/
|
||||
int x509_key_size_helper( char *buf, size_t size, const char *name )
|
||||
{
|
||||
char *p = buf;
|
||||
size_t n = size;
|
||||
int ret;
|
||||
|
||||
if( strlen( name ) + sizeof( " key size" ) > size )
|
||||
return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;
|
||||
|
||||
ret = snprintf( p, n, "%s key size", name );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Return an informational string describing the given OID
|
||||
*/
|
||||
const char *x509_oid_get_description( x509_buf *oid )
|
||||
{
|
||||
const char *desc = NULL;
|
||||
int ret;
|
||||
|
||||
ret = oid_get_extended_key_usage( oid, &desc );
|
||||
|
||||
if( ret != 0 )
|
||||
return( NULL );
|
||||
|
||||
return( desc );
|
||||
}
|
||||
|
||||
/* Return the x.y.z.... style numeric string for the given OID */
|
||||
int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
|
||||
{
|
||||
return oid_get_numeric_string( buf, size, oid );
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 if the x509_time is still valid, or 1 otherwise.
|
||||
*/
|
||||
#if defined(POLARSSL_HAVE_TIME)
|
||||
int x509parse_time_expired( const x509_time *to )
|
||||
{
|
||||
int year, mon, day;
|
||||
int hour, min, sec;
|
||||
|
||||
#if defined(_WIN32)
|
||||
SYSTEMTIME st;
|
||||
|
||||
GetLocalTime(&st);
|
||||
|
||||
year = st.wYear;
|
||||
mon = st.wMonth;
|
||||
day = st.wDay;
|
||||
hour = st.wHour;
|
||||
min = st.wMinute;
|
||||
sec = st.wSecond;
|
||||
#else
|
||||
struct tm *lt;
|
||||
time_t tt;
|
||||
|
||||
tt = time( NULL );
|
||||
lt = localtime( &tt );
|
||||
|
||||
year = lt->tm_year + 1900;
|
||||
mon = lt->tm_mon + 1;
|
||||
day = lt->tm_mday;
|
||||
hour = lt->tm_hour;
|
||||
min = lt->tm_min;
|
||||
sec = lt->tm_sec;
|
||||
#endif
|
||||
|
||||
if( year > to->year )
|
||||
return( 1 );
|
||||
|
||||
if( year == to->year &&
|
||||
mon > to->mon )
|
||||
return( 1 );
|
||||
|
||||
if( year == to->year &&
|
||||
mon == to->mon &&
|
||||
day > to->day )
|
||||
return( 1 );
|
||||
|
||||
if( year == to->year &&
|
||||
mon == to->mon &&
|
||||
day == to->day &&
|
||||
hour > to->hour )
|
||||
return( 1 );
|
||||
|
||||
if( year == to->year &&
|
||||
mon == to->mon &&
|
||||
day == to->day &&
|
||||
hour == to->hour &&
|
||||
min > to->min )
|
||||
return( 1 );
|
||||
|
||||
if( year == to->year &&
|
||||
mon == to->mon &&
|
||||
day == to->day &&
|
||||
hour == to->hour &&
|
||||
min == to->min &&
|
||||
sec > to->sec )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#else /* POLARSSL_HAVE_TIME */
|
||||
int x509parse_time_expired( const x509_time *to )
|
||||
{
|
||||
((void) to);
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_HAVE_TIME */
|
||||
|
||||
#endif /* POLARSSL_X509_USE_C */
|
267
library/x509_create.c
Normal file
267
library/x509_create.c
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* X.509 base functions for creating certificates / CSRs
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_X509_CREATE_C)
|
||||
|
||||
#include "polarssl/x509.h"
|
||||
#include "polarssl/asn1write.h"
|
||||
#include "polarssl/oid.h"
|
||||
|
||||
int x509write_string_to_names( asn1_named_data **head, char *name )
|
||||
{
|
||||
int ret = 0;
|
||||
char *s = name, *c = s;
|
||||
char *end = s + strlen( s );
|
||||
char *oid = NULL;
|
||||
int in_tag = 1;
|
||||
asn1_named_data *cur;
|
||||
|
||||
/* Clear existing chain if present */
|
||||
asn1_free_named_data_list( head );
|
||||
|
||||
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( ( cur = asn1_store_named_data( head, oid, strlen( oid ),
|
||||
(unsigned char *) s,
|
||||
c - s ) ) == NULL )
|
||||
{
|
||||
return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
|
||||
}
|
||||
|
||||
while( c < end && *(c + 1) == ' ' )
|
||||
c++;
|
||||
|
||||
s = c + 1;
|
||||
in_tag = 1;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* The first byte of the value in the asn1_named_data structure is reserved
|
||||
* to store the critical boolean for us
|
||||
*/
|
||||
int x509_set_extension( asn1_named_data **head, const char *oid, size_t oid_len,
|
||||
int critical, const unsigned char *val, size_t val_len )
|
||||
{
|
||||
asn1_named_data *cur;
|
||||
|
||||
if( ( cur = asn1_store_named_data( head, oid, oid_len,
|
||||
NULL, val_len + 1 ) ) == NULL )
|
||||
{
|
||||
return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
|
||||
}
|
||||
|
||||
cur->val.p[0] = critical;
|
||||
memcpy( cur->val.p + 1, val, val_len );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* RelativeDistinguishedName ::=
|
||||
* SET OF AttributeTypeAndValue
|
||||
*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
*/
|
||||
static int x509_write_name( unsigned char **p, unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
const unsigned char *name, size_t name_len )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
// Write PrintableString for all except OID_PKCS9_EMAIL
|
||||
//
|
||||
if( OID_SIZE( OID_PKCS9_EMAIL ) == oid_len &&
|
||||
memcmp( oid, OID_PKCS9_EMAIL, oid_len ) == 0 )
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_ia5_string( p, start,
|
||||
(const char *) name,
|
||||
name_len ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_printable_string( p, start,
|
||||
(const char *) name,
|
||||
name_len ) );
|
||||
}
|
||||
|
||||
// Write OID
|
||||
//
|
||||
ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SET ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int x509_write_names( unsigned char **p, unsigned char *start,
|
||||
asn1_named_data *first )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
asn1_named_data *cur = first;
|
||||
|
||||
while( cur != NULL )
|
||||
{
|
||||
ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p,
|
||||
cur->oid.len,
|
||||
cur->val.p, cur->val.len ) );
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int x509_write_sig( unsigned char **p, unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
unsigned char *sig, size_t size )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
if( *p - start < (int) size + 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
len = size;
|
||||
(*p) -= len;
|
||||
memcpy( *p, sig, len );
|
||||
|
||||
*--(*p) = 0;
|
||||
len += 1;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
|
||||
|
||||
// Write OID
|
||||
//
|
||||
ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid,
|
||||
oid_len, 0 ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
static int x509_write_extension( unsigned char **p, unsigned char *start,
|
||||
asn1_named_data *ext )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->val.p + 1,
|
||||
ext->val.len - 1 ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->val.len - 1 ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) );
|
||||
|
||||
if( ext->val.p[0] != 0 )
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_bool( p, start, 1 ) );
|
||||
}
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->oid.p,
|
||||
ext->oid.len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->oid.len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OID ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
/*
|
||||
* Extension ::= SEQUENCE {
|
||||
* extnID OBJECT IDENTIFIER,
|
||||
* critical BOOLEAN DEFAULT FALSE,
|
||||
* extnValue OCTET STRING
|
||||
* -- contains the DER encoding of an ASN.1 value
|
||||
* -- corresponding to the extension type identified
|
||||
* -- by extnID
|
||||
* }
|
||||
*/
|
||||
int x509_write_extensions( unsigned char **p, unsigned char *start,
|
||||
asn1_named_data *first )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
asn1_named_data *cur_ext = first;
|
||||
|
||||
while( cur_ext != NULL )
|
||||
{
|
||||
ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
|
||||
cur_ext = cur_ext->next;
|
||||
}
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
#endif /* POLARSSL_X509_CREATE_C */
|
740
library/x509_crl.c
Normal file
740
library/x509_crl.c
Normal file
@ -0,0 +1,740 @@
|
||||
/*
|
||||
* X.509 certificate and private key decoding
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* The ITU-T X.509 standard defines a certificate format for PKI.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc3279.txt
|
||||
* http://www.ietf.org/rfc/rfc3280.txt
|
||||
*
|
||||
* ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
|
||||
*
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_X509_CRL_PARSE_C)
|
||||
|
||||
#include "polarssl/x509_crl.h"
|
||||
#include "polarssl/oid.h"
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
#include "polarssl/pem.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MEMORY_C)
|
||||
#include "polarssl/memory.h"
|
||||
#else
|
||||
#define polarssl_malloc malloc
|
||||
#define polarssl_free free
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0), v2(1) }
|
||||
*/
|
||||
static int x509_crl_get_version( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *ver )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
|
||||
{
|
||||
if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
{
|
||||
*ver = 0;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* X.509 CRL v2 extensions (no extensions parsed yet.)
|
||||
*/
|
||||
static int x509_get_crl_ext( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
x509_buf *ext )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
/* Get explicit tag */
|
||||
if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
|
||||
{
|
||||
if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
return( 0 );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
while( *p < end )
|
||||
{
|
||||
if( ( ret = asn1_get_tag( p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
|
||||
|
||||
*p += len;
|
||||
}
|
||||
|
||||
if( *p != end )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* X.509 CRL v2 entry extensions (no extensions parsed yet.)
|
||||
*/
|
||||
static int x509_get_crl_entry_ext( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
x509_buf *ext )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
/* OPTIONAL */
|
||||
if (end <= *p)
|
||||
return( 0 );
|
||||
|
||||
ext->tag = **p;
|
||||
ext->p = *p;
|
||||
|
||||
/*
|
||||
* Get CRL-entry extension sequence header
|
||||
* crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( p, end, &ext->len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
{
|
||||
ext->p = NULL;
|
||||
return( 0 );
|
||||
}
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
|
||||
}
|
||||
|
||||
end = *p + ext->len;
|
||||
|
||||
if( end != *p + ext->len )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
while( *p < end )
|
||||
{
|
||||
if( ( ret = asn1_get_tag( p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
|
||||
|
||||
*p += len;
|
||||
}
|
||||
|
||||
if( *p != end )
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* X.509 CRL Entries
|
||||
*/
|
||||
static int x509_get_entries( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
x509_crl_entry *entry )
|
||||
{
|
||||
int ret;
|
||||
size_t entry_len;
|
||||
x509_crl_entry *cur_entry = entry;
|
||||
|
||||
if( *p == end )
|
||||
return( 0 );
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &entry_len,
|
||||
ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
|
||||
{
|
||||
if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
return( 0 );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
end = *p + entry_len;
|
||||
|
||||
while( *p < end )
|
||||
{
|
||||
size_t len2;
|
||||
const unsigned char *end2;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &len2,
|
||||
ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
cur_entry->raw.tag = **p;
|
||||
cur_entry->raw.p = *p;
|
||||
cur_entry->raw.len = len2;
|
||||
end2 = *p + len2;
|
||||
|
||||
if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if ( *p < end )
|
||||
{
|
||||
cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
|
||||
|
||||
if( cur_entry->next == NULL )
|
||||
return( POLARSSL_ERR_X509_MALLOC_FAILED );
|
||||
|
||||
cur_entry = cur_entry->next;
|
||||
memset( cur_entry, 0, sizeof( x509_crl_entry ) );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse one or more CRLs and add them to the chained list
|
||||
*/
|
||||
int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
unsigned char *p, *end;
|
||||
x509_crl *crl;
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
size_t use_len;
|
||||
pem_context pem;
|
||||
#endif
|
||||
|
||||
crl = chain;
|
||||
|
||||
/*
|
||||
* Check for valid input
|
||||
*/
|
||||
if( crl == NULL || buf == NULL )
|
||||
return( POLARSSL_ERR_X509_INVALID_INPUT );
|
||||
|
||||
while( crl->version != 0 && crl->next != NULL )
|
||||
crl = crl->next;
|
||||
|
||||
/*
|
||||
* Add new CRL on the end of the chain if needed.
|
||||
*/
|
||||
if ( crl->version != 0 && crl->next == NULL)
|
||||
{
|
||||
crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
|
||||
|
||||
if( crl->next == NULL )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_MALLOC_FAILED );
|
||||
}
|
||||
|
||||
crl = crl->next;
|
||||
memset( crl, 0, sizeof( x509_crl ) );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
pem_init( &pem );
|
||||
ret = pem_read_buffer( &pem,
|
||||
"-----BEGIN X509 CRL-----",
|
||||
"-----END X509 CRL-----",
|
||||
buf, NULL, 0, &use_len );
|
||||
|
||||
if( ret == 0 )
|
||||
{
|
||||
/*
|
||||
* Was PEM encoded
|
||||
*/
|
||||
buflen -= use_len;
|
||||
buf += use_len;
|
||||
|
||||
/*
|
||||
* Steal PEM buffer
|
||||
*/
|
||||
p = pem.buf;
|
||||
pem.buf = NULL;
|
||||
len = pem.buflen;
|
||||
pem_free( &pem );
|
||||
}
|
||||
else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
|
||||
{
|
||||
pem_free( &pem );
|
||||
return( ret );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* nope, copy the raw DER data
|
||||
*/
|
||||
p = (unsigned char *) polarssl_malloc( len = buflen );
|
||||
|
||||
if( p == NULL )
|
||||
return( POLARSSL_ERR_X509_MALLOC_FAILED );
|
||||
|
||||
memcpy( p, buf, buflen );
|
||||
|
||||
buflen = 0;
|
||||
}
|
||||
|
||||
crl->raw.p = p;
|
||||
crl->raw.len = len;
|
||||
end = p + len;
|
||||
|
||||
/*
|
||||
* CertificateList ::= SEQUENCE {
|
||||
* tbsCertList TBSCertList,
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signatureValue BIT STRING }
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
|
||||
}
|
||||
|
||||
if( len != (size_t) ( end - p ) )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
|
||||
/*
|
||||
* TBSCertList ::= SEQUENCE {
|
||||
*/
|
||||
crl->tbs.p = p;
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
end = p + len;
|
||||
crl->tbs.len = end - crl->tbs.p;
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
|
||||
* -- if present, MUST be v2
|
||||
*
|
||||
* signature AlgorithmIdentifier
|
||||
*/
|
||||
if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
|
||||
( ret = x509_get_alg_null( &p, end, &crl->sig_oid1 ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
crl->version++;
|
||||
|
||||
if( crl->version > 2 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
|
||||
&crl->sig_pk ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
|
||||
}
|
||||
|
||||
/*
|
||||
* issuer Name
|
||||
*/
|
||||
crl->issuer_raw.p = p;
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
crl->issuer_raw.len = p - crl->issuer_raw.p;
|
||||
|
||||
/*
|
||||
* thisUpdate Time
|
||||
* nextUpdate Time OPTIONAL
|
||||
*/
|
||||
if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
|
||||
{
|
||||
if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
|
||||
POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
|
||||
ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
|
||||
POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* revokedCertificates SEQUENCE OF SEQUENCE {
|
||||
* userCertificate CertificateSerialNumber,
|
||||
* revocationDate Time,
|
||||
* crlEntryExtensions Extensions OPTIONAL
|
||||
* -- if present, MUST be v2
|
||||
* } OPTIONAL
|
||||
*/
|
||||
if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* crlExtensions EXPLICIT Extensions OPTIONAL
|
||||
* -- if present, MUST be v2
|
||||
*/
|
||||
if( crl->version == 2 )
|
||||
{
|
||||
ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
|
||||
if( p != end )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
|
||||
end = crl->raw.p + crl->raw.len;
|
||||
|
||||
/*
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signatureValue BIT STRING
|
||||
*/
|
||||
if( ( ret = x509_get_alg_null( &p, end, &crl->sig_oid2 ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( crl->sig_oid1.len != crl->sig_oid2.len ||
|
||||
memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( p != end )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
|
||||
if( buflen > 0 )
|
||||
{
|
||||
crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
|
||||
|
||||
if( crl->next == NULL )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_MALLOC_FAILED );
|
||||
}
|
||||
|
||||
crl = crl->next;
|
||||
memset( crl, 0, sizeof( x509_crl ) );
|
||||
|
||||
return( x509parse_crl( crl, buf, buflen ) );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/*
|
||||
* Load one or more CRLs and add them to the chained list
|
||||
*/
|
||||
int x509parse_crlfile( x509_crl *chain, const char *path )
|
||||
{
|
||||
int ret;
|
||||
size_t n;
|
||||
unsigned char *buf;
|
||||
|
||||
if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = x509parse_crl( chain, buf, n );
|
||||
|
||||
memset( buf, 0, n + 1 );
|
||||
polarssl_free( buf );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
#if defined _MSC_VER && !defined snprintf
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined vsnprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif // vsnprintf
|
||||
|
||||
/*
|
||||
* Windows _snprintf and _vsnprintf are not compatible to linux versions.
|
||||
* Result value is not size of buffer needed, but -1 if no fit is possible.
|
||||
*
|
||||
* This fuction tries to 'fix' this by at least suggesting enlarging the
|
||||
* size by 20.
|
||||
*/
|
||||
static int compat_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int res = -1;
|
||||
|
||||
va_start( ap, format );
|
||||
|
||||
res = vsnprintf( str, size, format, ap );
|
||||
|
||||
va_end( ap );
|
||||
|
||||
// No quick fix possible
|
||||
if ( res < 0 )
|
||||
return( (int) size + 20 );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define snprintf compat_snprintf
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
|
||||
|
||||
#define SAFE_SNPRINTF() \
|
||||
{ \
|
||||
if( ret == -1 ) \
|
||||
return( -1 ); \
|
||||
\
|
||||
if ( (unsigned int) ret > n ) { \
|
||||
p[n - 1] = '\0'; \
|
||||
return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
|
||||
} \
|
||||
\
|
||||
n -= (unsigned int) ret; \
|
||||
p += (unsigned int) ret; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Return an informational string about the certificate.
|
||||
*/
|
||||
#define BEFORE_COLON 14
|
||||
#define BC "14"
|
||||
/*
|
||||
* Return an informational string about the CRL.
|
||||
*/
|
||||
int x509parse_crl_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_crl *crl )
|
||||
{
|
||||
int ret;
|
||||
size_t n;
|
||||
char *p;
|
||||
const char *desc;
|
||||
const x509_crl_entry *entry;
|
||||
|
||||
p = buf;
|
||||
n = size;
|
||||
|
||||
ret = snprintf( p, n, "%sCRL version : %d",
|
||||
prefix, crl->version );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = snprintf( p, n, "\n%sissuer name : ", prefix );
|
||||
SAFE_SNPRINTF();
|
||||
ret = x509parse_dn_gets( p, n, &crl->issuer );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = snprintf( p, n, "\n%sthis update : " \
|
||||
"%04d-%02d-%02d %02d:%02d:%02d", prefix,
|
||||
crl->this_update.year, crl->this_update.mon,
|
||||
crl->this_update.day, crl->this_update.hour,
|
||||
crl->this_update.min, crl->this_update.sec );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = snprintf( p, n, "\n%snext update : " \
|
||||
"%04d-%02d-%02d %02d:%02d:%02d", prefix,
|
||||
crl->next_update.year, crl->next_update.mon,
|
||||
crl->next_update.day, crl->next_update.hour,
|
||||
crl->next_update.min, crl->next_update.sec );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
entry = &crl->entry;
|
||||
|
||||
ret = snprintf( p, n, "\n%sRevoked certificates:",
|
||||
prefix );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
while( entry != NULL && entry->raw.len != 0 )
|
||||
{
|
||||
ret = snprintf( p, n, "\n%sserial number: ",
|
||||
prefix );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = x509parse_serial_gets( p, n, &entry->serial);
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = snprintf( p, n, " revocation date: " \
|
||||
"%04d-%02d-%02d %02d:%02d:%02d",
|
||||
entry->revocation_date.year, entry->revocation_date.mon,
|
||||
entry->revocation_date.day, entry->revocation_date.hour,
|
||||
entry->revocation_date.min, entry->revocation_date.sec );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
ret = snprintf( p, n, "\n%ssigned using : ", prefix );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
|
||||
if( ret != 0 )
|
||||
ret = snprintf( p, n, "???" );
|
||||
else
|
||||
ret = snprintf( p, n, "%s", desc );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = snprintf( p, n, "\n" );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
return( (int) ( size - n ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Unallocate all CRL data
|
||||
*/
|
||||
void x509_crl_free( x509_crl *crl )
|
||||
{
|
||||
x509_crl *crl_cur = crl;
|
||||
x509_crl *crl_prv;
|
||||
x509_name *name_cur;
|
||||
x509_name *name_prv;
|
||||
x509_crl_entry *entry_cur;
|
||||
x509_crl_entry *entry_prv;
|
||||
|
||||
if( crl == NULL )
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
name_cur = crl_cur->issuer.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
name_prv = name_cur;
|
||||
name_cur = name_cur->next;
|
||||
memset( name_prv, 0, sizeof( x509_name ) );
|
||||
polarssl_free( name_prv );
|
||||
}
|
||||
|
||||
entry_cur = crl_cur->entry.next;
|
||||
while( entry_cur != NULL )
|
||||
{
|
||||
entry_prv = entry_cur;
|
||||
entry_cur = entry_cur->next;
|
||||
memset( entry_prv, 0, sizeof( x509_crl_entry ) );
|
||||
polarssl_free( entry_prv );
|
||||
}
|
||||
|
||||
if( crl_cur->raw.p != NULL )
|
||||
{
|
||||
memset( crl_cur->raw.p, 0, crl_cur->raw.len );
|
||||
polarssl_free( crl_cur->raw.p );
|
||||
}
|
||||
|
||||
crl_cur = crl_cur->next;
|
||||
}
|
||||
while( crl_cur != NULL );
|
||||
|
||||
crl_cur = crl;
|
||||
do
|
||||
{
|
||||
crl_prv = crl_cur;
|
||||
crl_cur = crl_cur->next;
|
||||
|
||||
memset( crl_prv, 0, sizeof( x509_crl ) );
|
||||
if( crl_prv != crl )
|
||||
polarssl_free( crl_prv );
|
||||
}
|
||||
while( crl_cur != NULL );
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
426
library/x509_crt_write.c
Normal file
426
library/x509_crt_write.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* X.509 certificate writing
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* References:
|
||||
* - certificates: RFC 5280, updated by RFC 6818
|
||||
* - CSRs: PKCS#10 v1.7 aka RFC 2986
|
||||
* - attributes: PKCS#9 v2.0 aka RFC 2985
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_X509_CRT_WRITE_C)
|
||||
|
||||
#include "polarssl/x509_crt.h"
|
||||
#include "polarssl/oid.h"
|
||||
#include "polarssl/asn1write.h"
|
||||
#include "polarssl/sha1.h"
|
||||
|
||||
#if defined(POLARSSL_PEM_WRITE_C)
|
||||
#include "polarssl/pem.h"
|
||||
#endif /* POLARSSL_PEM_WRITE_C */
|
||||
|
||||
void x509write_crt_init( x509write_cert *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof(x509write_cert) );
|
||||
|
||||
mpi_init( &ctx->serial );
|
||||
ctx->version = X509_CRT_VERSION_3;
|
||||
}
|
||||
|
||||
void x509write_crt_free( x509write_cert *ctx )
|
||||
{
|
||||
mpi_free( &ctx->serial );
|
||||
|
||||
asn1_free_named_data_list( &ctx->subject );
|
||||
asn1_free_named_data_list( &ctx->issuer );
|
||||
asn1_free_named_data_list( &ctx->extensions );
|
||||
|
||||
memset( ctx, 0, sizeof(x509write_cert) );
|
||||
}
|
||||
|
||||
void x509write_crt_set_md_alg( x509write_cert *ctx, md_type_t md_alg )
|
||||
{
|
||||
ctx->md_alg = md_alg;
|
||||
}
|
||||
|
||||
void x509write_crt_set_subject_key( x509write_cert *ctx, pk_context *key )
|
||||
{
|
||||
ctx->subject_key = key;
|
||||
}
|
||||
|
||||
void x509write_crt_set_issuer_key( x509write_cert *ctx, pk_context *key )
|
||||
{
|
||||
ctx->issuer_key = key;
|
||||
}
|
||||
|
||||
int x509write_crt_set_subject_name( x509write_cert *ctx, char *subject_name )
|
||||
{
|
||||
return x509write_string_to_names( &ctx->subject, subject_name );
|
||||
}
|
||||
|
||||
int x509write_crt_set_issuer_name( x509write_cert *ctx, char *issuer_name )
|
||||
{
|
||||
return x509write_string_to_names( &ctx->issuer, issuer_name );
|
||||
}
|
||||
|
||||
int x509write_crt_set_serial( x509write_cert *ctx, const mpi *serial )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ( ret = mpi_copy( &ctx->serial, serial ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509write_crt_set_validity( x509write_cert *ctx, char *not_before,
|
||||
char *not_after )
|
||||
{
|
||||
if( strlen(not_before) != X509_RFC5280_UTC_TIME_LEN - 1 ||
|
||||
strlen(not_after) != X509_RFC5280_UTC_TIME_LEN - 1 )
|
||||
{
|
||||
return( POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA );
|
||||
}
|
||||
strncpy( ctx->not_before, not_before, X509_RFC5280_UTC_TIME_LEN );
|
||||
strncpy( ctx->not_after , not_after , X509_RFC5280_UTC_TIME_LEN );
|
||||
ctx->not_before[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
|
||||
ctx->not_after[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509write_crt_set_extension( x509write_cert *ctx,
|
||||
const char *oid, size_t oid_len,
|
||||
int critical,
|
||||
const unsigned char *val, size_t val_len )
|
||||
{
|
||||
return x509_set_extension( &ctx->extensions, oid, oid_len,
|
||||
critical, val, val_len );
|
||||
}
|
||||
|
||||
int x509write_crt_set_basic_constraints( x509write_cert *ctx,
|
||||
int is_ca, int max_pathlen )
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[9];
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
size_t len = 0;
|
||||
|
||||
memset( buf, 0, sizeof(buf) );
|
||||
|
||||
if( is_ca && max_pathlen > 127 )
|
||||
return( POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA );
|
||||
|
||||
if( is_ca )
|
||||
{
|
||||
if( max_pathlen >= 0 )
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_int( &c, buf, max_pathlen ) );
|
||||
}
|
||||
ASN1_CHK_ADD( len, asn1_write_bool( &c, buf, 1 ) );
|
||||
}
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return x509write_crt_set_extension( ctx, OID_BASIC_CONSTRAINTS,
|
||||
OID_SIZE( OID_BASIC_CONSTRAINTS ),
|
||||
0, buf + sizeof(buf) - len, len );
|
||||
}
|
||||
|
||||
int x509write_crt_set_subject_key_identifier( x509write_cert *ctx )
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[POLARSSL_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
size_t len = 0;
|
||||
|
||||
memset( buf, 0, sizeof(buf));
|
||||
ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->subject_key ) );
|
||||
|
||||
sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
|
||||
c = buf + sizeof(buf) - 20;
|
||||
len = 20;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_OCTET_STRING ) );
|
||||
|
||||
return x509write_crt_set_extension( ctx, OID_SUBJECT_KEY_IDENTIFIER,
|
||||
OID_SIZE( OID_SUBJECT_KEY_IDENTIFIER ),
|
||||
0, buf + sizeof(buf) - len, len );
|
||||
}
|
||||
|
||||
int x509write_crt_set_authority_key_identifier( x509write_cert *ctx )
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[POLARSSL_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
size_t len = 0;
|
||||
|
||||
memset( buf, 0, sizeof(buf));
|
||||
ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->issuer_key ) );
|
||||
|
||||
sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
|
||||
c = buf + sizeof(buf) - 20;
|
||||
len = 20;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONTEXT_SPECIFIC | 0 ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return x509write_crt_set_extension( ctx, OID_AUTHORITY_KEY_IDENTIFIER,
|
||||
OID_SIZE( OID_AUTHORITY_KEY_IDENTIFIER ),
|
||||
0, buf + sizeof(buf) - len, len );
|
||||
}
|
||||
|
||||
int x509write_crt_set_key_usage( x509write_cert *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_crt_set_extension( ctx, OID_KEY_USAGE,
|
||||
OID_SIZE( OID_KEY_USAGE ),
|
||||
1, buf, 4 );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509write_crt_set_ns_cert_type( x509write_cert *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_crt_set_extension( ctx, OID_NS_CERT_TYPE,
|
||||
OID_SIZE( OID_NS_CERT_TYPE ),
|
||||
0, buf, 4 );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int x509_write_time( unsigned char **p, unsigned char *start,
|
||||
const char *time, size_t size )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
/*
|
||||
* write ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
|
||||
*/
|
||||
if( time[0] == '2' && time[1] == '0' && time [2] < '5' )
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
|
||||
(const unsigned char *) time + 2,
|
||||
size - 2 ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_UTC_TIME ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
|
||||
(const unsigned char *) time,
|
||||
size ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_GENERALIZED_TIME ) );
|
||||
}
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
const char *sig_oid;
|
||||
size_t sig_oid_len = 0;
|
||||
unsigned char *c, *c2;
|
||||
unsigned char hash[64];
|
||||
unsigned char sig[POLARSSL_MPI_MAX_SIZE];
|
||||
unsigned char tmp_buf[2048];
|
||||
size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
|
||||
size_t len = 0;
|
||||
pk_type_t pk_alg;
|
||||
|
||||
/*
|
||||
* Prepare data to be signed in tmp_buf
|
||||
*/
|
||||
c = tmp_buf + sizeof( tmp_buf );
|
||||
|
||||
/* Signature algorithm needed in TBS, and later for actual signature */
|
||||
pk_alg = pk_get_type( ctx->issuer_key );
|
||||
if( pk_alg == POLARSSL_PK_ECKEY )
|
||||
pk_alg = POLARSSL_PK_ECDSA;
|
||||
|
||||
if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
|
||||
&sig_oid, &sig_oid_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
|
||||
*/
|
||||
ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
|
||||
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_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) );
|
||||
|
||||
/*
|
||||
* SubjectPublicKeyInfo
|
||||
*/
|
||||
ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->subject_key,
|
||||
tmp_buf, c - tmp_buf ) );
|
||||
c -= pub_len;
|
||||
len += pub_len;
|
||||
|
||||
/*
|
||||
* Subject ::= Name
|
||||
*/
|
||||
ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );
|
||||
|
||||
/*
|
||||
* Validity ::= SEQUENCE {
|
||||
* notBefore Time,
|
||||
* notAfter Time }
|
||||
*/
|
||||
sub_len = 0;
|
||||
|
||||
ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after,
|
||||
X509_RFC5280_UTC_TIME_LEN ) );
|
||||
|
||||
ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before,
|
||||
X509_RFC5280_UTC_TIME_LEN ) );
|
||||
|
||||
len += 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 ) );
|
||||
|
||||
/*
|
||||
* Issuer ::= Name
|
||||
*/
|
||||
ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->issuer ) );
|
||||
|
||||
/*
|
||||
* Signature ::= AlgorithmIdentifier
|
||||
*/
|
||||
ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, tmp_buf,
|
||||
sig_oid, strlen( sig_oid ), 0 ) );
|
||||
|
||||
/*
|
||||
* Serial ::= INTEGER
|
||||
*/
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, tmp_buf, &ctx->serial ) );
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
||||
*/
|
||||
sub_len = 0;
|
||||
ASN1_CHK_ADD( sub_len, asn1_write_int( &c, tmp_buf, ctx->version ) );
|
||||
len += 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_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) );
|
||||
|
||||
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 ) );
|
||||
|
||||
/*
|
||||
* Make signature
|
||||
*/
|
||||
md( md_info_from_type( ctx->md_alg ), c, len, hash );
|
||||
|
||||
if( ( ret = pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
|
||||
f_rng, p_rng ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to output buffer
|
||||
*/
|
||||
c2 = buf + size;
|
||||
ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf,
|
||||
sig_oid, sig_oid_len, sig, sig_len ) );
|
||||
|
||||
c2 -= len;
|
||||
memcpy( c2, c, len );
|
||||
|
||||
len += sig_and_oid_len;
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
|
||||
#define PEM_END_CRT "-----END CERTIFICATE-----\n"
|
||||
|
||||
#if defined(POLARSSL_PEM_WRITE_C)
|
||||
int x509write_crt_pem( x509write_cert *crt, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
unsigned char output_buf[4096];
|
||||
size_t olen = 0;
|
||||
|
||||
if( ( ret = x509write_crt_der( crt, output_buf, sizeof(output_buf),
|
||||
f_rng, p_rng ) ) < 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT,
|
||||
output_buf + sizeof(output_buf) - ret,
|
||||
ret, buf, size, &olen ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_PEM_WRITE_C */
|
||||
|
||||
#endif /* POLARSSL_X509_CRT_WRITE_C */
|
439
library/x509_csr.c
Normal file
439
library/x509_csr.c
Normal file
@ -0,0 +1,439 @@
|
||||
/*
|
||||
* X.509 Certificate Signing Request (CSR) parsing
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* The ITU-T X.509 standard defines a certificate format for PKI.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc3279.txt
|
||||
* http://www.ietf.org/rfc/rfc3280.txt
|
||||
*
|
||||
* ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
|
||||
*
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_X509_CSR_PARSE_C)
|
||||
|
||||
#include "polarssl/x509_csr.h"
|
||||
#include "polarssl/oid.h"
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
#include "polarssl/pem.h"
|
||||
#endif
|
||||
#if defined(POLARSSL_ASN1_WRITE_C)
|
||||
#include "polarssl/asn1write.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MEMORY_C)
|
||||
#include "polarssl/memory.h"
|
||||
#else
|
||||
#define polarssl_malloc malloc
|
||||
#define polarssl_free free
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0) }
|
||||
*/
|
||||
static int x509_csr_get_version( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *ver )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
|
||||
{
|
||||
if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
{
|
||||
*ver = 0;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a CSR
|
||||
*/
|
||||
int x509parse_csr( x509_csr *csr, const unsigned char *buf, size_t buflen )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
unsigned char *p, *end;
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
size_t use_len;
|
||||
pem_context pem;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check for valid input
|
||||
*/
|
||||
if( csr == NULL || buf == NULL )
|
||||
return( POLARSSL_ERR_X509_INVALID_INPUT );
|
||||
|
||||
memset( csr, 0, sizeof( x509_csr ) );
|
||||
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
pem_init( &pem );
|
||||
ret = pem_read_buffer( &pem,
|
||||
"-----BEGIN CERTIFICATE REQUEST-----",
|
||||
"-----END CERTIFICATE REQUEST-----",
|
||||
buf, NULL, 0, &use_len );
|
||||
|
||||
if( ret == 0 )
|
||||
{
|
||||
/*
|
||||
* Was PEM encoded
|
||||
*/
|
||||
buflen -= use_len;
|
||||
buf += use_len;
|
||||
|
||||
/*
|
||||
* Steal PEM buffer
|
||||
*/
|
||||
p = pem.buf;
|
||||
pem.buf = NULL;
|
||||
len = pem.buflen;
|
||||
pem_free( &pem );
|
||||
}
|
||||
else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
|
||||
{
|
||||
pem_free( &pem );
|
||||
return( ret );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* nope, copy the raw DER data
|
||||
*/
|
||||
p = (unsigned char *) polarssl_malloc( len = buflen );
|
||||
|
||||
if( p == NULL )
|
||||
return( POLARSSL_ERR_X509_MALLOC_FAILED );
|
||||
|
||||
memcpy( p, buf, buflen );
|
||||
|
||||
buflen = 0;
|
||||
}
|
||||
|
||||
csr->raw.p = p;
|
||||
csr->raw.len = len;
|
||||
end = p + len;
|
||||
|
||||
/*
|
||||
* CertificationRequest ::= SEQUENCE {
|
||||
* certificationRequestInfo CertificationRequestInfo,
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signature BIT STRING
|
||||
* }
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
|
||||
}
|
||||
|
||||
if( len != (size_t) ( end - p ) )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
|
||||
/*
|
||||
* CertificationRequestInfo ::= SEQUENCE {
|
||||
*/
|
||||
csr->cri.p = p;
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
end = p + len;
|
||||
csr->cri.len = end - csr->cri.p;
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0) }
|
||||
*/
|
||||
if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
csr->version++;
|
||||
|
||||
if( csr->version != 1 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
|
||||
}
|
||||
|
||||
/*
|
||||
* subject Name
|
||||
*/
|
||||
csr->subject_raw.p = p;
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
csr->subject_raw.len = p - csr->subject_raw.p;
|
||||
|
||||
/*
|
||||
* subjectPKInfo SubjectPublicKeyInfo
|
||||
*/
|
||||
if( ( ret = pk_parse_get_pubkey( &p, end, &csr->pk ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* attributes [0] Attributes
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
|
||||
}
|
||||
// TODO Parse Attributes / extension requests
|
||||
|
||||
p += len;
|
||||
|
||||
end = csr->raw.p + csr->raw.len;
|
||||
|
||||
/*
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signature BIT STRING
|
||||
*/
|
||||
if( ( ret = x509_get_alg_null( &p, end, &csr->sig_oid ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_sig_alg( &csr->sig_oid, &csr->sig_md,
|
||||
&csr->sig_pk ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_sig( &p, end, &csr->sig ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( p != end )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_FS_IO)
|
||||
/*
|
||||
* Load a CSR into the structure
|
||||
*/
|
||||
int x509parse_csrfile( x509_csr *csr, const char *path )
|
||||
{
|
||||
int ret;
|
||||
size_t n;
|
||||
unsigned char *buf;
|
||||
|
||||
if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = x509parse_csr( csr, buf, n );
|
||||
|
||||
memset( buf, 0, n + 1 );
|
||||
polarssl_free( buf );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* POLARSSL_FS_IO */
|
||||
|
||||
#if defined _MSC_VER && !defined snprintf
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined vsnprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif // vsnprintf
|
||||
|
||||
/*
|
||||
* Windows _snprintf and _vsnprintf are not compatible to linux versions.
|
||||
* Result value is not size of buffer needed, but -1 if no fit is possible.
|
||||
*
|
||||
* This fuction tries to 'fix' this by at least suggesting enlarging the
|
||||
* size by 20.
|
||||
*/
|
||||
static int compat_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int res = -1;
|
||||
|
||||
va_start( ap, format );
|
||||
|
||||
res = vsnprintf( str, size, format, ap );
|
||||
|
||||
va_end( ap );
|
||||
|
||||
// No quick fix possible
|
||||
if ( res < 0 )
|
||||
return( (int) size + 20 );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define snprintf compat_snprintf
|
||||
#endif
|
||||
|
||||
#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
|
||||
|
||||
#define SAFE_SNPRINTF() \
|
||||
{ \
|
||||
if( ret == -1 ) \
|
||||
return( -1 ); \
|
||||
\
|
||||
if ( (unsigned int) ret > n ) { \
|
||||
p[n - 1] = '\0'; \
|
||||
return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
|
||||
} \
|
||||
\
|
||||
n -= (unsigned int) ret; \
|
||||
p += (unsigned int) ret; \
|
||||
}
|
||||
|
||||
#define BEFORE_COLON 14
|
||||
#define BC "14"
|
||||
/*
|
||||
* Return an informational string about the CSR.
|
||||
*/
|
||||
int x509parse_csr_info( char *buf, size_t size, const char *prefix,
|
||||
const x509_csr *csr )
|
||||
{
|
||||
int ret;
|
||||
size_t n;
|
||||
char *p;
|
||||
const char *desc;
|
||||
char key_size_str[BEFORE_COLON];
|
||||
|
||||
p = buf;
|
||||
n = size;
|
||||
|
||||
ret = snprintf( p, n, "%sCSR version : %d",
|
||||
prefix, csr->version );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = snprintf( p, n, "\n%ssubject name : ", prefix );
|
||||
SAFE_SNPRINTF();
|
||||
ret = x509parse_dn_gets( p, n, &csr->subject );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = snprintf( p, n, "\n%ssigned using : ", prefix );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = oid_get_sig_alg_desc( &csr->sig_oid, &desc );
|
||||
if( ret != 0 )
|
||||
ret = snprintf( p, n, "???" );
|
||||
else
|
||||
ret = snprintf( p, n, "%s", desc );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
|
||||
pk_get_name( &csr->pk ) ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
|
||||
(int) pk_get_size( &csr->pk ) );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
return( (int) ( size - n ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Unallocate all CSR data
|
||||
*/
|
||||
void x509_csr_free( x509_csr *csr )
|
||||
{
|
||||
x509_name *name_cur;
|
||||
x509_name *name_prv;
|
||||
|
||||
if( csr == NULL )
|
||||
return;
|
||||
|
||||
pk_free( &csr->pk );
|
||||
|
||||
name_cur = csr->subject.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
name_prv = name_cur;
|
||||
name_cur = name_cur->next;
|
||||
memset( name_prv, 0, sizeof( x509_name ) );
|
||||
polarssl_free( name_prv );
|
||||
}
|
||||
|
||||
if( csr->raw.p != NULL )
|
||||
{
|
||||
memset( csr->raw.p, 0, csr->raw.len );
|
||||
polarssl_free( csr->raw.p );
|
||||
}
|
||||
|
||||
memset( csr, 0, sizeof( x509_csr ) );
|
||||
}
|
||||
|
||||
#endif /* POLARSSL_X509_CSR_PARSE_C */
|
244
library/x509_csr_write.c
Normal file
244
library/x509_csr_write.c
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* X.509 Certificate Signing Request writing
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* References:
|
||||
* - CSRs: PKCS#10 v1.7 aka RFC 2986
|
||||
* - attributes: PKCS#9 v2.0 aka RFC 2985
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_X509_CSR_WRITE_C)
|
||||
|
||||
#include "polarssl/x509_csr.h"
|
||||
#include "polarssl/oid.h"
|
||||
#include "polarssl/asn1write.h"
|
||||
|
||||
#if defined(POLARSSL_PEM_WRITE_C)
|
||||
#include "polarssl/pem.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void x509write_csr_init( x509write_csr *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof(x509write_csr) );
|
||||
}
|
||||
|
||||
void x509write_csr_free( x509write_csr *ctx )
|
||||
{
|
||||
asn1_free_named_data_list( &ctx->subject );
|
||||
asn1_free_named_data_list( &ctx->extensions );
|
||||
|
||||
memset( ctx, 0, sizeof(x509write_csr) );
|
||||
}
|
||||
|
||||
void x509write_csr_set_md_alg( x509write_csr *ctx, md_type_t md_alg )
|
||||
{
|
||||
ctx->md_alg = md_alg;
|
||||
}
|
||||
|
||||
void x509write_csr_set_key( x509write_csr *ctx, pk_context *key )
|
||||
{
|
||||
ctx->key = key;
|
||||
}
|
||||
|
||||
int x509write_csr_set_subject_name( x509write_csr *ctx, char *subject_name )
|
||||
{
|
||||
return x509write_string_to_names( &ctx->subject, subject_name );
|
||||
}
|
||||
|
||||
int x509write_csr_set_extension( x509write_csr *ctx,
|
||||
const char *oid, size_t oid_len,
|
||||
const unsigned char *val, size_t val_len )
|
||||
{
|
||||
return x509_set_extension( &ctx->extensions, oid, oid_len,
|
||||
0, val, val_len );
|
||||
}
|
||||
|
||||
int x509write_csr_set_key_usage( x509write_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( x509write_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_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
const char *sig_oid;
|
||||
size_t sig_oid_len = 0;
|
||||
unsigned char *c, *c2;
|
||||
unsigned char hash[64];
|
||||
unsigned char sig[POLARSSL_MPI_MAX_SIZE];
|
||||
unsigned char tmp_buf[2048];
|
||||
size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
|
||||
size_t len = 0;
|
||||
pk_type_t pk_alg;
|
||||
|
||||
/*
|
||||
* Prepare data to be signed in tmp_buf
|
||||
*/
|
||||
c = tmp_buf + sizeof( tmp_buf );
|
||||
|
||||
ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
|
||||
|
||||
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,
|
||||
OID_SIZE( 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( pub_len, pk_write_pubkey_der( ctx->key,
|
||||
tmp_buf, c - tmp_buf ) );
|
||||
c -= pub_len;
|
||||
len += pub_len;
|
||||
|
||||
/*
|
||||
* Subject ::= Name
|
||||
*/
|
||||
ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );
|
||||
|
||||
/*
|
||||
* 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_len( &c, tmp_buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
/*
|
||||
* Prepare signature
|
||||
*/
|
||||
md( md_info_from_type( ctx->md_alg ), c, len, hash );
|
||||
|
||||
pk_alg = pk_get_type( ctx->key );
|
||||
if( pk_alg == POLARSSL_PK_ECKEY )
|
||||
pk_alg = POLARSSL_PK_ECDSA;
|
||||
|
||||
if( ( ret = pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
|
||||
f_rng, p_rng ) ) != 0 ||
|
||||
( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
|
||||
&sig_oid, &sig_oid_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to output buffer
|
||||
*/
|
||||
c2 = buf + size;
|
||||
ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf,
|
||||
sig_oid, sig_oid_len, sig, sig_len ) );
|
||||
|
||||
c2 -= len;
|
||||
memcpy( c2, c, len );
|
||||
|
||||
len += sig_and_oid_len;
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
|
||||
#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
|
||||
|
||||
#if defined(POLARSSL_PEM_WRITE_C)
|
||||
int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
unsigned char output_buf[4096];
|
||||
size_t olen = 0;
|
||||
|
||||
if( ( ret = x509write_csr_der( ctx, output_buf, sizeof(output_buf),
|
||||
f_rng, p_rng ) ) < 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
|
||||
output_buf + sizeof(output_buf) - ret,
|
||||
ret, buf, size, &olen ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_PEM_WRITE_C */
|
||||
|
||||
#endif /* POLARSSL_X509_CSR_WRITE_C */
|
@ -1,869 +0,0 @@
|
||||
/*
|
||||
* X509 buffer writing functionality
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* References:
|
||||
* - certificates: RFC 5280, updated by RFC 6818
|
||||
* - CSRs: PKCS#10 v1.7 aka RFC 2986
|
||||
* - attributes: PKCS#9 v2.0 aka RFC 2985
|
||||
*/
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#if defined(POLARSSL_X509_WRITE_C)
|
||||
|
||||
#include "polarssl/asn1write.h"
|
||||
#include "polarssl/x509write.h"
|
||||
#include "polarssl/x509.h"
|
||||
#include "polarssl/md.h"
|
||||
#include "polarssl/oid.h"
|
||||
|
||||
#include "polarssl/sha1.h"
|
||||
|
||||
#if defined(POLARSSL_PEM_WRITE_C)
|
||||
#include "polarssl/pem.h"
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_MEMORY_C)
|
||||
#include "polarssl/memory.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define polarssl_malloc malloc
|
||||
#define polarssl_free free
|
||||
#endif
|
||||
|
||||
static int x509write_string_to_names( asn1_named_data **head, char *name )
|
||||
{
|
||||
int ret = 0;
|
||||
char *s = name, *c = s;
|
||||
char *end = s + strlen( s );
|
||||
char *oid = NULL;
|
||||
int in_tag = 1;
|
||||
asn1_named_data *cur;
|
||||
|
||||
/* Clear existing chain if present */
|
||||
asn1_free_named_data_list( head );
|
||||
|
||||
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( ( cur = asn1_store_named_data( head, oid, strlen( oid ),
|
||||
(unsigned char *) s,
|
||||
c - s ) ) == NULL )
|
||||
{
|
||||
return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
|
||||
}
|
||||
|
||||
while( c < end && *(c + 1) == ' ' )
|
||||
c++;
|
||||
|
||||
s = c + 1;
|
||||
in_tag = 1;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
void x509write_csr_init( x509write_csr *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof(x509write_csr) );
|
||||
}
|
||||
|
||||
void x509write_csr_free( x509write_csr *ctx )
|
||||
{
|
||||
asn1_free_named_data_list( &ctx->subject );
|
||||
asn1_free_named_data_list( &ctx->extensions );
|
||||
|
||||
memset( ctx, 0, sizeof(x509write_csr) );
|
||||
}
|
||||
|
||||
void x509write_csr_set_md_alg( x509write_csr *ctx, md_type_t md_alg )
|
||||
{
|
||||
ctx->md_alg = md_alg;
|
||||
}
|
||||
|
||||
void x509write_csr_set_key( x509write_csr *ctx, pk_context *key )
|
||||
{
|
||||
ctx->key = key;
|
||||
}
|
||||
|
||||
int x509write_csr_set_subject_name( x509write_csr *ctx, char *subject_name )
|
||||
{
|
||||
return x509write_string_to_names( &ctx->subject, subject_name );
|
||||
}
|
||||
|
||||
/* The first byte of the value in the asn1_named_data structure is reserved
|
||||
* to store the critical boolean for us
|
||||
*/
|
||||
static int x509_set_extension( asn1_named_data **head,
|
||||
const char *oid, size_t oid_len,
|
||||
int critical,
|
||||
const unsigned char *val, size_t val_len )
|
||||
{
|
||||
asn1_named_data *cur;
|
||||
|
||||
if( ( cur = asn1_store_named_data( head, oid, oid_len,
|
||||
NULL, val_len + 1 ) ) == NULL )
|
||||
{
|
||||
return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
|
||||
}
|
||||
|
||||
cur->val.p[0] = critical;
|
||||
memcpy( cur->val.p + 1, val, val_len );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509write_csr_set_extension( x509write_csr *ctx,
|
||||
const char *oid, size_t oid_len,
|
||||
const unsigned char *val, size_t val_len )
|
||||
{
|
||||
return x509_set_extension( &ctx->extensions, oid, oid_len,
|
||||
0, val, val_len );
|
||||
}
|
||||
|
||||
int x509write_csr_set_key_usage( x509write_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( x509write_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 );
|
||||
}
|
||||
|
||||
void x509write_crt_init( x509write_cert *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof(x509write_cert) );
|
||||
|
||||
mpi_init( &ctx->serial );
|
||||
ctx->version = X509_CRT_VERSION_3;
|
||||
}
|
||||
|
||||
void x509write_crt_free( x509write_cert *ctx )
|
||||
{
|
||||
mpi_free( &ctx->serial );
|
||||
|
||||
asn1_free_named_data_list( &ctx->subject );
|
||||
asn1_free_named_data_list( &ctx->issuer );
|
||||
asn1_free_named_data_list( &ctx->extensions );
|
||||
|
||||
memset( ctx, 0, sizeof(x509write_csr) );
|
||||
}
|
||||
|
||||
void x509write_crt_set_md_alg( x509write_cert *ctx, md_type_t md_alg )
|
||||
{
|
||||
ctx->md_alg = md_alg;
|
||||
}
|
||||
|
||||
void x509write_crt_set_subject_key( x509write_cert *ctx, pk_context *key )
|
||||
{
|
||||
ctx->subject_key = key;
|
||||
}
|
||||
|
||||
void x509write_crt_set_issuer_key( x509write_cert *ctx, pk_context *key )
|
||||
{
|
||||
ctx->issuer_key = key;
|
||||
}
|
||||
|
||||
int x509write_crt_set_subject_name( x509write_cert *ctx, char *subject_name )
|
||||
{
|
||||
return x509write_string_to_names( &ctx->subject, subject_name );
|
||||
}
|
||||
|
||||
int x509write_crt_set_issuer_name( x509write_cert *ctx, char *issuer_name )
|
||||
{
|
||||
return x509write_string_to_names( &ctx->issuer, issuer_name );
|
||||
}
|
||||
|
||||
int x509write_crt_set_serial( x509write_cert *ctx, const mpi *serial )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ( ret = mpi_copy( &ctx->serial, serial ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509write_crt_set_validity( x509write_cert *ctx, char *not_before,
|
||||
char *not_after )
|
||||
{
|
||||
if( strlen(not_before) != X509_RFC5280_UTC_TIME_LEN - 1 ||
|
||||
strlen(not_after) != X509_RFC5280_UTC_TIME_LEN - 1 )
|
||||
{
|
||||
return( POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA );
|
||||
}
|
||||
strncpy( ctx->not_before, not_before, X509_RFC5280_UTC_TIME_LEN );
|
||||
strncpy( ctx->not_after , not_after , X509_RFC5280_UTC_TIME_LEN );
|
||||
ctx->not_before[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
|
||||
ctx->not_after[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509write_crt_set_extension( x509write_cert *ctx,
|
||||
const char *oid, size_t oid_len,
|
||||
int critical,
|
||||
const unsigned char *val, size_t val_len )
|
||||
{
|
||||
return x509_set_extension( &ctx->extensions, oid, oid_len,
|
||||
critical, val, val_len );
|
||||
}
|
||||
|
||||
int x509write_crt_set_basic_constraints( x509write_cert *ctx,
|
||||
int is_ca, int max_pathlen )
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[9];
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
size_t len = 0;
|
||||
|
||||
memset( buf, 0, sizeof(buf) );
|
||||
|
||||
if( is_ca && max_pathlen > 127 )
|
||||
return( POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA );
|
||||
|
||||
if( is_ca )
|
||||
{
|
||||
if( max_pathlen >= 0 )
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_int( &c, buf, max_pathlen ) );
|
||||
}
|
||||
ASN1_CHK_ADD( len, asn1_write_bool( &c, buf, 1 ) );
|
||||
}
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return x509write_crt_set_extension( ctx, OID_BASIC_CONSTRAINTS,
|
||||
OID_SIZE( OID_BASIC_CONSTRAINTS ),
|
||||
0, buf + sizeof(buf) - len, len );
|
||||
}
|
||||
|
||||
int x509write_crt_set_subject_key_identifier( x509write_cert *ctx )
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[POLARSSL_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
size_t len = 0;
|
||||
|
||||
memset( buf, 0, sizeof(buf));
|
||||
ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->subject_key ) );
|
||||
|
||||
sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
|
||||
c = buf + sizeof(buf) - 20;
|
||||
len = 20;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_OCTET_STRING ) );
|
||||
|
||||
return x509write_crt_set_extension( ctx, OID_SUBJECT_KEY_IDENTIFIER,
|
||||
OID_SIZE( OID_SUBJECT_KEY_IDENTIFIER ),
|
||||
0, buf + sizeof(buf) - len, len );
|
||||
}
|
||||
|
||||
int x509write_crt_set_authority_key_identifier( x509write_cert *ctx )
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[POLARSSL_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
size_t len = 0;
|
||||
|
||||
memset( buf, 0, sizeof(buf));
|
||||
ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->issuer_key ) );
|
||||
|
||||
sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
|
||||
c = buf + sizeof(buf) - 20;
|
||||
len = 20;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONTEXT_SPECIFIC | 0 ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return x509write_crt_set_extension( ctx, OID_AUTHORITY_KEY_IDENTIFIER,
|
||||
OID_SIZE( OID_AUTHORITY_KEY_IDENTIFIER ),
|
||||
0, buf + sizeof(buf) - len, len );
|
||||
}
|
||||
|
||||
int x509write_crt_set_key_usage( x509write_cert *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_crt_set_extension( ctx, OID_KEY_USAGE,
|
||||
OID_SIZE( OID_KEY_USAGE ),
|
||||
1, buf, 4 );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509write_crt_set_ns_cert_type( x509write_cert *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_crt_set_extension( ctx, OID_NS_CERT_TYPE,
|
||||
OID_SIZE( OID_NS_CERT_TYPE ),
|
||||
0, buf, 4 );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* RelativeDistinguishedName ::=
|
||||
* SET OF AttributeTypeAndValue
|
||||
*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
*/
|
||||
static int x509_write_name( unsigned char **p, unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
const unsigned char *name, size_t name_len )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
// Write PrintableString for all except OID_PKCS9_EMAIL
|
||||
//
|
||||
if( OID_SIZE( OID_PKCS9_EMAIL ) == oid_len &&
|
||||
memcmp( oid, OID_PKCS9_EMAIL, oid_len ) == 0 )
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_ia5_string( p, start,
|
||||
(const char *) name,
|
||||
name_len ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_printable_string( p, start,
|
||||
(const char *) name,
|
||||
name_len ) );
|
||||
}
|
||||
|
||||
// Write OID
|
||||
//
|
||||
ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SET ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
static int x509_write_names( unsigned char **p, unsigned char *start,
|
||||
asn1_named_data *first )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
asn1_named_data *cur = first;
|
||||
|
||||
while( cur != NULL )
|
||||
{
|
||||
ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p,
|
||||
cur->oid.len,
|
||||
cur->val.p, cur->val.len ) );
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
static int x509_write_sig( unsigned char **p, unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
unsigned char *sig, size_t size )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
if( *p - start < (int) size + 1 )
|
||||
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
|
||||
|
||||
len = size;
|
||||
(*p) -= len;
|
||||
memcpy( *p, sig, len );
|
||||
|
||||
*--(*p) = 0;
|
||||
len += 1;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
|
||||
|
||||
// Write OID
|
||||
//
|
||||
ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid,
|
||||
oid_len, 0 ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
static int x509_write_time( unsigned char **p, unsigned char *start,
|
||||
const char *time, size_t size )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
/*
|
||||
* write ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
|
||||
*/
|
||||
if( time[0] == '2' && time[1] == '0' && time [2] < '5' )
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
|
||||
(const unsigned char *) time + 2,
|
||||
size - 2 ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_UTC_TIME ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
|
||||
(const unsigned char *) time,
|
||||
size ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_GENERALIZED_TIME ) );
|
||||
}
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
static int x509_write_extension( unsigned char **p, unsigned char *start,
|
||||
asn1_named_data *ext )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->val.p + 1,
|
||||
ext->val.len - 1 ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->val.len - 1 ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) );
|
||||
|
||||
if( ext->val.p[0] != 0 )
|
||||
{
|
||||
ASN1_CHK_ADD( len, asn1_write_bool( p, start, 1 ) );
|
||||
}
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->oid.p,
|
||||
ext->oid.len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->oid.len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OID ) );
|
||||
|
||||
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
/*
|
||||
* Extension ::= SEQUENCE {
|
||||
* extnID OBJECT IDENTIFIER,
|
||||
* critical BOOLEAN DEFAULT FALSE,
|
||||
* extnValue OCTET STRING
|
||||
* -- contains the DER encoding of an ASN.1 value
|
||||
* -- corresponding to the extension type identified
|
||||
* -- by extnID
|
||||
* }
|
||||
*/
|
||||
static int x509_write_extensions( unsigned char **p, unsigned char *start,
|
||||
asn1_named_data *first )
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
asn1_named_data *cur_ext = first;
|
||||
|
||||
while( cur_ext != NULL )
|
||||
{
|
||||
ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
|
||||
cur_ext = cur_ext->next;
|
||||
}
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
const char *sig_oid;
|
||||
size_t sig_oid_len = 0;
|
||||
unsigned char *c, *c2;
|
||||
unsigned char hash[64];
|
||||
unsigned char sig[POLARSSL_MPI_MAX_SIZE];
|
||||
unsigned char tmp_buf[2048];
|
||||
size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
|
||||
size_t len = 0;
|
||||
pk_type_t pk_alg;
|
||||
|
||||
/*
|
||||
* Prepare data to be signed in tmp_buf
|
||||
*/
|
||||
c = tmp_buf + sizeof( tmp_buf );
|
||||
|
||||
ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
|
||||
|
||||
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,
|
||||
OID_SIZE( 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( pub_len, pk_write_pubkey_der( ctx->key,
|
||||
tmp_buf, c - tmp_buf ) );
|
||||
c -= pub_len;
|
||||
len += pub_len;
|
||||
|
||||
/*
|
||||
* Subject ::= Name
|
||||
*/
|
||||
ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );
|
||||
|
||||
/*
|
||||
* 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_len( &c, tmp_buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
/*
|
||||
* Prepare signature
|
||||
*/
|
||||
md( md_info_from_type( ctx->md_alg ), c, len, hash );
|
||||
|
||||
pk_alg = pk_get_type( ctx->key );
|
||||
if( pk_alg == POLARSSL_PK_ECKEY )
|
||||
pk_alg = POLARSSL_PK_ECDSA;
|
||||
|
||||
if( ( ret = pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
|
||||
f_rng, p_rng ) ) != 0 ||
|
||||
( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
|
||||
&sig_oid, &sig_oid_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to output buffer
|
||||
*/
|
||||
c2 = buf + size;
|
||||
ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf,
|
||||
sig_oid, sig_oid_len, sig, sig_len ) );
|
||||
|
||||
c2 -= len;
|
||||
memcpy( c2, c, len );
|
||||
|
||||
len += sig_and_oid_len;
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
const char *sig_oid;
|
||||
size_t sig_oid_len = 0;
|
||||
unsigned char *c, *c2;
|
||||
unsigned char hash[64];
|
||||
unsigned char sig[POLARSSL_MPI_MAX_SIZE];
|
||||
unsigned char tmp_buf[2048];
|
||||
size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
|
||||
size_t len = 0;
|
||||
pk_type_t pk_alg;
|
||||
|
||||
/*
|
||||
* Prepare data to be signed in tmp_buf
|
||||
*/
|
||||
c = tmp_buf + sizeof( tmp_buf );
|
||||
|
||||
/* Signature algorithm needed in TBS, and later for actual signature */
|
||||
pk_alg = pk_get_type( ctx->issuer_key );
|
||||
if( pk_alg == POLARSSL_PK_ECKEY )
|
||||
pk_alg = POLARSSL_PK_ECDSA;
|
||||
|
||||
if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
|
||||
&sig_oid, &sig_oid_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
|
||||
*/
|
||||
ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
|
||||
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_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) );
|
||||
|
||||
/*
|
||||
* SubjectPublicKeyInfo
|
||||
*/
|
||||
ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->subject_key,
|
||||
tmp_buf, c - tmp_buf ) );
|
||||
c -= pub_len;
|
||||
len += pub_len;
|
||||
|
||||
/*
|
||||
* Subject ::= Name
|
||||
*/
|
||||
ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );
|
||||
|
||||
/*
|
||||
* Validity ::= SEQUENCE {
|
||||
* notBefore Time,
|
||||
* notAfter Time }
|
||||
*/
|
||||
sub_len = 0;
|
||||
|
||||
ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after,
|
||||
X509_RFC5280_UTC_TIME_LEN ) );
|
||||
|
||||
ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before,
|
||||
X509_RFC5280_UTC_TIME_LEN ) );
|
||||
|
||||
len += 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 ) );
|
||||
|
||||
/*
|
||||
* Issuer ::= Name
|
||||
*/
|
||||
ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->issuer ) );
|
||||
|
||||
/*
|
||||
* Signature ::= AlgorithmIdentifier
|
||||
*/
|
||||
ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, tmp_buf,
|
||||
sig_oid, strlen( sig_oid ), 0 ) );
|
||||
|
||||
/*
|
||||
* Serial ::= INTEGER
|
||||
*/
|
||||
ASN1_CHK_ADD( len, asn1_write_mpi( &c, tmp_buf, &ctx->serial ) );
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
||||
*/
|
||||
sub_len = 0;
|
||||
ASN1_CHK_ADD( sub_len, asn1_write_int( &c, tmp_buf, ctx->version ) );
|
||||
len += 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_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) );
|
||||
|
||||
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 ) );
|
||||
|
||||
/*
|
||||
* Make signature
|
||||
*/
|
||||
md( md_info_from_type( ctx->md_alg ), c, len, hash );
|
||||
|
||||
if( ( ret = pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
|
||||
f_rng, p_rng ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to output buffer
|
||||
*/
|
||||
c2 = buf + size;
|
||||
ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf,
|
||||
sig_oid, sig_oid_len, sig, sig_len ) );
|
||||
|
||||
c2 -= len;
|
||||
memcpy( c2, c, len );
|
||||
|
||||
len += sig_and_oid_len;
|
||||
ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
|
||||
ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||
|
||||
return( len );
|
||||
}
|
||||
|
||||
#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
|
||||
#define PEM_END_CRT "-----END CERTIFICATE-----\n"
|
||||
|
||||
#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
|
||||
#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
|
||||
|
||||
#if defined(POLARSSL_PEM_WRITE_C)
|
||||
int x509write_crt_pem( x509write_cert *crt, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
unsigned char output_buf[4096];
|
||||
size_t olen = 0;
|
||||
|
||||
if( ( ret = x509write_crt_der( crt, output_buf, sizeof(output_buf),
|
||||
f_rng, p_rng ) ) < 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT,
|
||||
output_buf + sizeof(output_buf) - ret,
|
||||
ret, buf, size, &olen ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
unsigned char output_buf[4096];
|
||||
size_t olen = 0;
|
||||
|
||||
if( ( ret = x509write_csr_der( ctx, output_buf, sizeof(output_buf),
|
||||
f_rng, p_rng ) ) < 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
|
||||
output_buf + sizeof(output_buf) - ret,
|
||||
ret, buf, size, &olen ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_BASE64_C */
|
||||
|
||||
#endif
|
@ -33,16 +33,16 @@
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include "polarssl/x509write.h"
|
||||
#include "polarssl/pk.h"
|
||||
#include "polarssl/error.h"
|
||||
|
||||
#if !defined(POLARSSL_X509_WRITE_C) || !defined(POLARSSL_FS_IO)
|
||||
#if !defined(POLARSSL_PK_WRITE_C) || !defined(POLARSSL_FS_IO)
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
((void) argc);
|
||||
((void) argv);
|
||||
|
||||
printf( "POLARSSL_X509_WRITE_C and/or POLARSSL_FS_IO not defined.\n" );
|
||||
printf( "POLARSSL_PK_WRITE_C and/or POLARSSL_FS_IO not defined.\n" );
|
||||
return( 0 );
|
||||
}
|
||||
#else
|
||||
|
@ -42,7 +42,7 @@
|
||||
#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_ENTROPY_C) || \
|
||||
!defined(POLARSSL_SSL_TLS_C) || !defined(POLARSSL_SSL_CLI_C) || \
|
||||
!defined(POLARSSL_NET_C) || !defined(POLARSSL_RSA_C) || \
|
||||
!defined(POLARSSL_X509_PARSE_C) || !defined(POLARSSL_FS_IO) || \
|
||||
!defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_FS_IO) || \
|
||||
!defined(POLARSSL_CTR_DRBG_C)
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
@ -52,7 +52,7 @@ int main( int argc, char *argv[] )
|
||||
printf("POLARSSL_BIGNUM_C and/or POLARSSL_ENTROPY_C and/or "
|
||||
"POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_CLI_C and/or "
|
||||
"POLARSSL_NET_C and/or POLARSSL_RSA_C and/or "
|
||||
"POLARSSL_X509_PARSE_C and/or POLARSSL_FS_IO and/or "
|
||||
"POLARSSL_X509_CRT_PARSE_C and/or POLARSSL_FS_IO and/or "
|
||||
"POLARSSL_CTR_DRBG_C not defined.\n");
|
||||
return( 0 );
|
||||
}
|
||||
@ -282,14 +282,14 @@ int main( int argc, char *argv[] )
|
||||
if( ret < 0 )
|
||||
{
|
||||
printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
|
||||
x509_free( &crt );
|
||||
x509_crt_free( &crt );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( opt.permissive == 0 && ret > 0 )
|
||||
{
|
||||
printf( " failed\n ! x509parse_crt failed to parse %d certificates\n\n", ret );
|
||||
x509_free( &crt );
|
||||
x509_crt_free( &crt );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -305,7 +305,7 @@ int main( int argc, char *argv[] )
|
||||
if( ret == -1 )
|
||||
{
|
||||
printf( " failed\n ! x509parse_cert_info returned %d\n\n", ret );
|
||||
x509_free( &crt );
|
||||
x509_crt_free( &crt );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -344,7 +344,7 @@ int main( int argc, char *argv[] )
|
||||
printf( " ok\n" );
|
||||
}
|
||||
|
||||
x509_free( &crt );
|
||||
x509_crt_free( &crt );
|
||||
}
|
||||
else if( opt.mode == MODE_SSL )
|
||||
{
|
||||
@ -447,8 +447,8 @@ exit:
|
||||
|
||||
if( server_fd )
|
||||
net_close( server_fd );
|
||||
x509_free( &cacert );
|
||||
x509_free( &clicert );
|
||||
x509_crt_free( &cacert );
|
||||
x509_crt_free( &clicert );
|
||||
pk_free( &pkey );
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
@ -33,21 +33,19 @@
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include "polarssl/x509write.h"
|
||||
#include "polarssl/x509_csr.h"
|
||||
#include "polarssl/entropy.h"
|
||||
#include "polarssl/ctr_drbg.h"
|
||||
#include "polarssl/error.h"
|
||||
|
||||
#if !defined(POLARSSL_X509_WRITE_C) || !defined(POLARSSL_X509_PARSE_C) || \
|
||||
!defined(POLARSSL_FS_IO) || \
|
||||
#if !defined(POLARSSL_X509_CSR_WRITE_C) || !defined(POLARSSL_FS_IO) || \
|
||||
!defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_CTR_DRBG_C)
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
((void) argc);
|
||||
((void) argv);
|
||||
|
||||
printf( "POLARSSL_X509_WRITE_C and/or POLARSSL_X509_PARSE_C and/or "
|
||||
"POLARSSL_FS_IO and/or "
|
||||
printf( "POLARSSL_X509_CSR_WRITE_C and/or POLARSSL_FS_IO and/or "
|
||||
"POLARSSL_ENTROPY_C and/or POLARSSL_CTR_DRBG_C "
|
||||
"not defined.\n");
|
||||
return( 0 );
|
||||
|
@ -33,13 +33,14 @@
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include "polarssl/x509write.h"
|
||||
#include "polarssl/x509_crt.h"
|
||||
#include "polarssl/x509_csr.h"
|
||||
#include "polarssl/entropy.h"
|
||||
#include "polarssl/ctr_drbg.h"
|
||||
#include "polarssl/error.h"
|
||||
|
||||
#if !defined(POLARSSL_X509_WRITE_C) || !defined(POLARSSL_X509_PARSE_C) || \
|
||||
!defined(POLARSSL_FS_IO) || \
|
||||
#if !defined(POLARSSL_X509_CRT_WRITE_C) || \
|
||||
!defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_FS_IO) || \
|
||||
!defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_CTR_DRBG_C) || \
|
||||
!defined(POLARSSL_ERROR_C)
|
||||
int main( int argc, char *argv[] )
|
||||
@ -47,7 +48,7 @@ int main( int argc, char *argv[] )
|
||||
((void) argc);
|
||||
((void) argv);
|
||||
|
||||
printf( "POLARSSL_X509_WRITE_C and/or POLARSSL_X509_PARSE_C and/or "
|
||||
printf( "POLARSSL_X509_CRT_WRITE_C and/or POLARSSL_X509_CRT_PARSE_C and/or "
|
||||
"POLARSSL_FS_IO and/or "
|
||||
"POLARSSL_ENTROPY_C and/or POLARSSL_CTR_DRBG_C and/or "
|
||||
"POLARSSL_ERROR_C not defined.\n");
|
||||
|
@ -33,17 +33,17 @@
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include "polarssl/x509.h"
|
||||
#include "polarssl/x509_crl.h"
|
||||
|
||||
#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_RSA_C) || \
|
||||
!defined(POLARSSL_X509_PARSE_C) || !defined(POLARSSL_FS_IO)
|
||||
!defined(POLARSSL_X509_CRL_PARSE_C) || !defined(POLARSSL_FS_IO)
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
((void) argc);
|
||||
((void) argv);
|
||||
|
||||
printf("POLARSSL_BIGNUM_C and/or POLARSSL_RSA_C and/or "
|
||||
"POLARSSL_X509_PARSE_C and/or POLARSSL_FS_IO not defined.\n");
|
||||
"POLARSSL_X509_CRL_PARSE_C and/or POLARSSL_FS_IO not defined.\n");
|
||||
return( 0 );
|
||||
}
|
||||
#else
|
||||
|
@ -33,17 +33,17 @@
|
||||
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include "polarssl/x509.h"
|
||||
#include "polarssl/x509_csr.h"
|
||||
|
||||
#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_RSA_C) || \
|
||||
!defined(POLARSSL_X509_PARSE_C) || !defined(POLARSSL_FS_IO)
|
||||
!defined(POLARSSL_X509_CSR_PARSE_C) || !defined(POLARSSL_FS_IO)
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
((void) argc);
|
||||
((void) argv);
|
||||
|
||||
printf("POLARSSL_BIGNUM_C and/or POLARSSL_RSA_C and/or "
|
||||
"POLARSSL_X509_PARSE_C and/or POLARSSL_FS_IO not defined.\n");
|
||||
"POLARSSL_X509_CSR_PARSE_C and/or POLARSSL_FS_IO not defined.\n");
|
||||
return( 0 );
|
||||
}
|
||||
#else
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* BEGIN_HEADER */
|
||||
#include <polarssl/x509.h>
|
||||
#include <polarssl/x509_crt.h>
|
||||
#include <polarssl/x509_crl.h>
|
||||
#include <polarssl/pem.h>
|
||||
#include <polarssl/oid.h>
|
||||
|
||||
@ -26,11 +27,11 @@ int verify_all( void *data, x509_cert *crt, int certificate_depth, int *flags )
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
* depends_on:POLARSSL_X509_PARSE_C:POLARSSL_BIGNUM_C
|
||||
* depends_on:POLARSSL_BIGNUM_C
|
||||
* END_DEPENDENCIES
|
||||
*/
|
||||
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO:POLARSSL_X509_CRT_PARSE_C */
|
||||
void x509_cert_info( char *crt_file, char *result_str )
|
||||
{
|
||||
x509_cert crt;
|
||||
@ -43,7 +44,7 @@ void x509_cert_info( char *crt_file, char *result_str )
|
||||
TEST_ASSERT( x509parse_crtfile( &crt, crt_file ) == 0 );
|
||||
res = x509parse_cert_info( buf, 2000, "", &crt );
|
||||
|
||||
x509_free( &crt );
|
||||
x509_crt_free( &crt );
|
||||
|
||||
TEST_ASSERT( res != -1 );
|
||||
TEST_ASSERT( res != -2 );
|
||||
@ -52,7 +53,7 @@ void x509_cert_info( char *crt_file, char *result_str )
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO:POLARSSL_X509_CRL_PARSE_C */
|
||||
void x509_crl_info( char *crl_file, char *result_str )
|
||||
{
|
||||
x509_crl crl;
|
||||
@ -74,7 +75,7 @@ void x509_crl_info( char *crl_file, char *result_str )
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO:POLARSSL_X509_CRT_PARSE_C */
|
||||
void x509_verify( char *crt_file, char *ca_file, char *crl_file,
|
||||
char *cn_name_str, int result, int flags_result,
|
||||
char *verify_callback )
|
||||
@ -109,8 +110,8 @@ void x509_verify( char *crt_file, char *ca_file, char *crl_file,
|
||||
|
||||
res = x509parse_verify( &crt, &ca, &crl, cn_name, &flags, f_vrfy, NULL );
|
||||
|
||||
x509_free( &crt );
|
||||
x509_free( &ca );
|
||||
x509_crt_free( &crt );
|
||||
x509_crt_free( &ca );
|
||||
x509_crl_free( &crl );
|
||||
|
||||
TEST_ASSERT( res == ( result ) );
|
||||
@ -118,7 +119,7 @@ void x509_verify( char *crt_file, char *ca_file, char *crl_file,
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO:POLARSSL_X509_USE_C */
|
||||
void x509_dn_gets( char *crt_file, char *entity, char *result_str )
|
||||
{
|
||||
x509_cert crt;
|
||||
@ -136,7 +137,7 @@ void x509_dn_gets( char *crt_file, char *entity, char *result_str )
|
||||
else
|
||||
TEST_ASSERT( "Unknown entity" == 0 );
|
||||
|
||||
x509_free( &crt );
|
||||
x509_crt_free( &crt );
|
||||
|
||||
TEST_ASSERT( res != -1 );
|
||||
TEST_ASSERT( res != -2 );
|
||||
@ -145,7 +146,7 @@ void x509_dn_gets( char *crt_file, char *entity, char *result_str )
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_FS_IO:POLARSSL_X509_USE_C */
|
||||
void x509_time_expired( char *crt_file, char *entity, int result )
|
||||
{
|
||||
x509_cert crt;
|
||||
@ -161,11 +162,11 @@ void x509_time_expired( char *crt_file, char *entity, int result )
|
||||
else
|
||||
TEST_ASSERT( "Unknown entity" == 0 );
|
||||
|
||||
x509_free( &crt );
|
||||
x509_crt_free( &crt );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_X509_CRT_PARSE_C */
|
||||
void x509parse_crt( char *crt_data, char *result_str, int result )
|
||||
{
|
||||
x509_cert crt;
|
||||
@ -190,11 +191,11 @@ void x509parse_crt( char *crt_data, char *result_str, int result )
|
||||
TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
|
||||
}
|
||||
|
||||
x509_free( &crt );
|
||||
x509_crt_free( &crt );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_X509_CRL_PARSE_C */
|
||||
void x509parse_crl( char *crl_data, char *result_str, int result )
|
||||
{
|
||||
x509_crl crl;
|
||||
@ -223,7 +224,7 @@ void x509parse_crl( char *crl_data, char *result_str, int result )
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_X509_CRT_PARSE_C */
|
||||
void x509_selftest()
|
||||
{
|
||||
TEST_ASSERT( x509_self_test( 0 ) == 0 );
|
||||
|
@ -1,16 +1,16 @@
|
||||
/* BEGIN_HEADER */
|
||||
#include <polarssl/x509write.h>
|
||||
#include <polarssl/x509.h>
|
||||
#include <polarssl/x509_crt.h>
|
||||
#include <polarssl/x509_csr.h>
|
||||
#include <polarssl/pem.h>
|
||||
#include <polarssl/oid.h>
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
* depends_on:POLARSSL_X509_WRITE_C:POLARSSL_BIGNUM_C:POLARSSL_FS_IO
|
||||
* depends_on:POLARSSL_BIGNUM_C:POLARSSL_FS_IO:POLARSSL_PK_PARSE_C
|
||||
* END_DEPENDENCIES
|
||||
*/
|
||||
|
||||
/* BEGIN_CASE depends_on:POLARSSL_PEM_C */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_PEM_WRITE_C:POLARSSL_X509_CSR_WRITE_C */
|
||||
void x509_csr_check( char *key_file, int md_type,
|
||||
char *cert_req_check_file )
|
||||
{
|
||||
@ -53,7 +53,7 @@ void x509_csr_check( char *key_file, int md_type,
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:POLARSSL_PEM_C */
|
||||
/* BEGIN_CASE depends_on:POLARSSL_PEM_WRITE_C:POLARSSL_X509_CRT_WRITE_C */
|
||||
void x509_crt_check( char *subject_key_file, char *subject_pwd,
|
||||
char *subject_name, char *issuer_key_file,
|
||||
char *issuer_pwd, char *issuer_name,
|
||||
|
Loading…
Reference in New Issue
Block a user