dolphin/Externals/polarssl/library/x509_create.c
Ryan Houdek a48e284317 Update external polarssl to 1.3.8
There were some fixes back on March 13th, 2014 for fixing compiling on MIPS64.
Also some fixes on June 25th, 2014 for SPARC64 fixes.

Probably more things, but those are what I care about.
2014-09-08 02:21:18 -05:00

318 lines
10 KiB
C

/*
* X.509 base functions for creating certificates / CSRs
*
* Copyright (C) 2006-2014, 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.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_X509_CREATE_C)
#include "polarssl/x509.h"
#include "polarssl/asn1write.h"
#include "polarssl/oid.h"
#if defined(_MSC_VER) && !defined strncasecmp && !defined(EFIX64) && \
!defined(EFI32)
#define strncasecmp _strnicmp
#endif
typedef struct {
const char *name;
size_t name_len;
const char*oid;
} x509_attr_descriptor_t;
#define ADD_STRLEN( s ) s, sizeof( s ) - 1
static const x509_attr_descriptor_t x509_attrs[] =
{
{ ADD_STRLEN( "CN" ), OID_AT_CN },
{ ADD_STRLEN( "commonName" ), OID_AT_CN },
{ ADD_STRLEN( "C" ), OID_AT_COUNTRY },
{ ADD_STRLEN( "countryName" ), OID_AT_COUNTRY },
{ ADD_STRLEN( "O" ), OID_AT_ORGANIZATION },
{ ADD_STRLEN( "organizationName" ), OID_AT_ORGANIZATION },
{ ADD_STRLEN( "L" ), OID_AT_LOCALITY },
{ ADD_STRLEN( "locality" ), OID_AT_LOCALITY },
{ ADD_STRLEN( "R" ), OID_PKCS9_EMAIL },
{ ADD_STRLEN( "OU" ), OID_AT_ORG_UNIT },
{ ADD_STRLEN( "organizationalUnitName" ), OID_AT_ORG_UNIT },
{ ADD_STRLEN( "ST" ), OID_AT_STATE },
{ ADD_STRLEN( "stateOrProvinceName" ), OID_AT_STATE },
{ ADD_STRLEN( "emailAddress" ), OID_PKCS9_EMAIL },
{ ADD_STRLEN( "serialNumber" ), OID_AT_SERIAL_NUMBER },
{ ADD_STRLEN( "postalAddress" ), OID_AT_POSTAL_ADDRESS },
{ ADD_STRLEN( "postalCode" ), OID_AT_POSTAL_CODE },
{ ADD_STRLEN( "dnQualifier" ), OID_AT_DN_QUALIFIER },
{ ADD_STRLEN( "title" ), OID_AT_TITLE },
{ ADD_STRLEN( "surName" ), OID_AT_SUR_NAME },
{ ADD_STRLEN( "SN" ), OID_AT_SUR_NAME },
{ ADD_STRLEN( "givenName" ), OID_AT_GIVEN_NAME },
{ ADD_STRLEN( "GN" ), OID_AT_GIVEN_NAME },
{ ADD_STRLEN( "initials" ), OID_AT_INITIALS },
{ ADD_STRLEN( "pseudonym" ), OID_AT_PSEUDONYM },
{ ADD_STRLEN( "generationQualifier" ), OID_AT_GENERATION_QUALIFIER },
{ ADD_STRLEN( "domainComponent" ), OID_DOMAIN_COMPONENT },
{ ADD_STRLEN( "DC" ), OID_DOMAIN_COMPONENT },
{ NULL, 0, NULL }
};
static const char *x509_at_oid_from_name( const char *name, size_t name_len )
{
const x509_attr_descriptor_t *cur;
for( cur = x509_attrs; cur->name != NULL; cur++ )
if( cur->name_len == name_len &&
strncasecmp( cur->name, name, name_len ) == 0 )
break;
return( cur->oid );
}
int x509_string_to_names( asn1_named_data **head, const char *name )
{
int ret = 0;
const char *s = name, *c = s;
const char *end = s + strlen( s );
const char *oid = NULL;
int in_tag = 1;
/* Clear existing chain if present */
asn1_free_named_data_list( head );
while( c <= end )
{
if( in_tag && *c == '=' )
{
if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL )
{
ret = POLARSSL_ERR_X509_UNKNOWN_OID;
goto exit;
}
s = c + 1;
in_tag = 0;
}
if( !in_tag && ( *c == ',' || c == end ) )
{
if( asn1_store_named_data( head, oid, strlen( oid ),
(unsigned char *) s,
c - s ) == NULL )
{
return( POLARSSL_ERR_X509_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_X509_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( (int) 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( (int) 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( (int) 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( (int) 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( (int) len );
}
#endif /* POLARSSL_X509_CREATE_C */