mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-22 22:15:43 +01:00
Generalized the x509write_csr_set_key_usage() function and key_usage
storage
This commit is contained in:
parent
6db915b5a9
commit
e5eae76bf0
@ -93,7 +93,10 @@
|
|||||||
/** Returns the size of the binary string, without the trailing \\0 */
|
/** Returns the size of the binary string, without the trailing \\0 */
|
||||||
#define OID_SIZE(x) (sizeof(x) - 1)
|
#define OID_SIZE(x) (sizeof(x) - 1)
|
||||||
|
|
||||||
/** Compares two asn1_buf structures for the same OID */
|
/** Compares two asn1_buf structures for the same OID. Only works for
|
||||||
|
* 'defined' oid_str values (OID_HMAC_SHA1), you cannot use a 'unsigned
|
||||||
|
* char *oid' here!
|
||||||
|
*/
|
||||||
#define OID_CMP(oid_str, oid_buf) \
|
#define OID_CMP(oid_str, oid_buf) \
|
||||||
( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
|
( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
|
||||||
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0 )
|
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0 )
|
||||||
@ -139,6 +142,17 @@ typedef struct _asn1_sequence
|
|||||||
}
|
}
|
||||||
asn1_sequence;
|
asn1_sequence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for a sequence or list of 'named' ASN.1 data items
|
||||||
|
*/
|
||||||
|
typedef struct _asn1_named_data
|
||||||
|
{
|
||||||
|
asn1_buf oid; /**< The object identifier. */
|
||||||
|
asn1_buf val; /**< The named value. */
|
||||||
|
struct _asn1_named_data *next; /**< The next entry in the sequence. */
|
||||||
|
}
|
||||||
|
asn1_named_data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the length of an ASN.1 element.
|
* Get the length of an ASN.1 element.
|
||||||
* Updates the pointer to immediately behind the length.
|
* Updates the pointer to immediately behind the length.
|
||||||
@ -286,6 +300,25 @@ int asn1_get_alg_null( unsigned char **p,
|
|||||||
const unsigned char *end,
|
const unsigned char *end,
|
||||||
asn1_buf *alg );
|
asn1_buf *alg );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a specific named_data entry in a sequence or list based on the OID.
|
||||||
|
*
|
||||||
|
* \param list The list to seek through
|
||||||
|
* \param oid The OID to look for
|
||||||
|
* \param len Size of the OID
|
||||||
|
*
|
||||||
|
* \return NULL if not found, or a pointer to the existing entry.
|
||||||
|
*/
|
||||||
|
asn1_named_data *asn1_find_named_data( asn1_named_data *list,
|
||||||
|
const char *oid, size_t len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a asn1_named_data entry
|
||||||
|
*
|
||||||
|
* \param entry The named data entry to free
|
||||||
|
*/
|
||||||
|
void asn1_free_named_data( asn1_named_data *entry );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -169,13 +169,7 @@ typedef asn1_bitstring x509_bitstring;
|
|||||||
* Container for ASN1 named information objects.
|
* Container for ASN1 named information objects.
|
||||||
* It allows for Relative Distinguished Names (e.g. cn=polarssl,ou=code,etc.).
|
* It allows for Relative Distinguished Names (e.g. cn=polarssl,ou=code,etc.).
|
||||||
*/
|
*/
|
||||||
typedef struct _x509_name
|
typedef asn1_named_data x509_name;
|
||||||
{
|
|
||||||
x509_buf oid; /**< The object identifier. */
|
|
||||||
x509_buf val; /**< The named value. */
|
|
||||||
struct _x509_name *next; /**< The next named information object. */
|
|
||||||
}
|
|
||||||
x509_name;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for a sequence of ASN.1 items
|
* Container for a sequence of ASN.1 items
|
||||||
|
@ -80,7 +80,7 @@ typedef struct _x509_csr
|
|||||||
rsa_context *rsa;
|
rsa_context *rsa;
|
||||||
x509_req_name *subject;
|
x509_req_name *subject;
|
||||||
md_type_t md_alg;
|
md_type_t md_alg;
|
||||||
unsigned char key_usage;
|
asn1_named_data *extensions;
|
||||||
}
|
}
|
||||||
x509_csr;
|
x509_csr;
|
||||||
|
|
||||||
@ -131,8 +131,10 @@ void x509write_csr_set_md_alg( x509_csr *ctx, md_type_t md_alg );
|
|||||||
*
|
*
|
||||||
* \param ctx CSR context to use
|
* \param ctx CSR context to use
|
||||||
* \param key_usage key usage bitstring to set
|
* \param key_usage key usage bitstring to set
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or POLARSSL_ERR_X509WRITE_MALLOC_FAILED
|
||||||
*/
|
*/
|
||||||
void x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage );
|
int x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Free the contents of a CSR context
|
* \brief Free the contents of a CSR context
|
||||||
|
@ -343,4 +343,32 @@ int asn1_get_alg_null( unsigned char **p,
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void asn1_free_named_data( asn1_named_data *cur )
|
||||||
|
{
|
||||||
|
if( cur == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
polarssl_free( cur->oid.p );
|
||||||
|
polarssl_free( cur->val.p );
|
||||||
|
|
||||||
|
memset( cur, 0, sizeof( asn1_named_data ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
asn1_named_data *asn1_find_named_data( asn1_named_data *list,
|
||||||
|
const char *oid, size_t len )
|
||||||
|
{
|
||||||
|
while( list != NULL )
|
||||||
|
{
|
||||||
|
if( list->oid.len == len &&
|
||||||
|
memcmp( list->oid.p, oid, len ) == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return( list );
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,6 +49,7 @@ void x509write_csr_init( x509_csr *ctx )
|
|||||||
void x509write_csr_free( x509_csr *ctx )
|
void x509write_csr_free( x509_csr *ctx )
|
||||||
{
|
{
|
||||||
x509_req_name *cur;
|
x509_req_name *cur;
|
||||||
|
asn1_named_data *cur_ext;
|
||||||
|
|
||||||
while( ( cur = ctx->subject ) != NULL )
|
while( ( cur = ctx->subject ) != NULL )
|
||||||
{
|
{
|
||||||
@ -56,6 +57,13 @@ void x509write_csr_free( x509_csr *ctx )
|
|||||||
polarssl_free( cur );
|
polarssl_free( cur );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while( ( cur_ext = ctx->extensions ) != NULL )
|
||||||
|
{
|
||||||
|
ctx->extensions = cur_ext->next;
|
||||||
|
asn1_free_named_data( cur_ext );
|
||||||
|
polarssl_free( cur_ext );
|
||||||
|
}
|
||||||
|
|
||||||
memset( ctx, 0, sizeof(x509_csr) );
|
memset( ctx, 0, sizeof(x509_csr) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,9 +156,49 @@ exit:
|
|||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
void x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage )
|
int x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage )
|
||||||
{
|
{
|
||||||
ctx->key_usage = key_usage;
|
asn1_named_data *cur;
|
||||||
|
unsigned char *c;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if( ( cur = asn1_find_named_data( ctx->extensions, OID_KEY_USAGE,
|
||||||
|
OID_SIZE( OID_KEY_USAGE ) ) ) == NULL )
|
||||||
|
{
|
||||||
|
cur = polarssl_malloc( sizeof(asn1_named_data) );
|
||||||
|
if( cur == NULL )
|
||||||
|
return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
|
||||||
|
|
||||||
|
memset( cur, 0, sizeof(asn1_named_data) );
|
||||||
|
|
||||||
|
cur->oid.len = OID_SIZE( OID_KEY_USAGE );
|
||||||
|
cur->oid.p = polarssl_malloc( cur->oid.len );
|
||||||
|
if( cur->oid.p == NULL )
|
||||||
|
{
|
||||||
|
free( cur );
|
||||||
|
return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
cur->val.len = 4;
|
||||||
|
cur->val.p = polarssl_malloc( cur->val.len );
|
||||||
|
if( cur->val.p == NULL )
|
||||||
|
{
|
||||||
|
free( cur->oid.p );
|
||||||
|
free( cur );
|
||||||
|
return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy( cur->oid.p, OID_KEY_USAGE, OID_SIZE( OID_KEY_USAGE ) );
|
||||||
|
|
||||||
|
cur->next = ctx->extensions;
|
||||||
|
ctx->extensions = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = cur->val.p + cur->val.len;
|
||||||
|
if( ( len = asn1_write_bitstring( &c, cur->val.p, &key_usage, 6 ) ) < 0 )
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int x509write_pubkey_der( rsa_context *rsa, unsigned char *buf, size_t size )
|
int x509write_pubkey_der( rsa_context *rsa, unsigned char *buf, size_t size )
|
||||||
@ -306,43 +354,50 @@ int x509write_csr_der( x509_csr *ctx, unsigned char *buf, size_t size )
|
|||||||
unsigned char hash[64];
|
unsigned char hash[64];
|
||||||
unsigned char sig[POLARSSL_MPI_MAX_SIZE];
|
unsigned char sig[POLARSSL_MPI_MAX_SIZE];
|
||||||
unsigned char tmp_buf[2048];
|
unsigned char tmp_buf[2048];
|
||||||
size_t sub_len = 0, pub_len = 0, sig_len = 0, ext_len = 0;
|
size_t sub_len = 0, pub_len = 0, sig_len = 0;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
x509_req_name *cur = ctx->subject;
|
x509_req_name *cur = ctx->subject;
|
||||||
|
asn1_named_data *cur_ext = ctx->extensions;
|
||||||
|
|
||||||
c = tmp_buf + 2048 - 1;
|
c = tmp_buf + 2048 - 1;
|
||||||
|
|
||||||
/*
|
while( cur_ext != NULL )
|
||||||
* Extension ::= SEQUENCE {
|
|
||||||
* extnID OBJECT IDENTIFIER,
|
|
||||||
* extnValue OCTET STRING }
|
|
||||||
*/
|
|
||||||
if( ctx->key_usage )
|
|
||||||
{
|
{
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_bitstring( &c, tmp_buf, &ctx->key_usage, 6 ) );
|
size_t ext_len = 0;
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
|
|
||||||
|
ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->val.p,
|
||||||
|
cur_ext->val.len ) );
|
||||||
|
ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->val.len ) );
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OCTET_STRING ) );
|
ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OCTET_STRING ) );
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_oid( &c, tmp_buf, OID_KEY_USAGE ) );
|
|
||||||
|
ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->oid.p,
|
||||||
|
cur_ext->oid.len ) );
|
||||||
|
ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->oid.len ) );
|
||||||
|
ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OID ) );
|
||||||
|
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
|
ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||||
|
|
||||||
|
cur_ext = cur_ext->next;
|
||||||
|
|
||||||
|
len += ext_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ext_len )
|
if( len )
|
||||||
{
|
{
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
|
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||||
|
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
|
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SET ) );
|
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SET ) );
|
||||||
|
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ ) );
|
ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ ) );
|
||||||
|
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
|
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
|
||||||
ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
len += ext_len;
|
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
|
||||||
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, ext_len ) );
|
|
||||||
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
|
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
|
||||||
|
|
||||||
ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->E ) );
|
ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->E ) );
|
||||||
|
Loading…
Reference in New Issue
Block a user