Rewrote x509 certificate request writing to use structure for storing
diff --git a/library/x509write.c b/library/x509write.c
index 7aa65ce..213add6 100644
--- a/library/x509write.c
+++ b/library/x509write.c
@@ -33,6 +33,126 @@
#include "polarssl/md.h"
#include "polarssl/oid.h"
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#include <stdlib.h>
+#define polarssl_malloc malloc
+#define polarssl_free free
+#endif
+
+void x509cert_req_init( x509_cert_req *ctx )
+{
+ memset( ctx, 0, sizeof(x509_cert_req) );
+}
+
+void x509cert_req_free( x509_cert_req *ctx )
+{
+ x509_req_name *cur;
+
+ while( ( cur = ctx->subject ) != NULL )
+ {
+ ctx->subject = cur->next;
+ polarssl_free( cur );
+ }
+
+ memset( ctx, 0, sizeof(x509_cert_req) );
+}
+
+void x509cert_req_set_md_alg( x509_cert_req *ctx, md_type_t md_alg )
+{
+ ctx->md_alg = md_alg;
+}
+
+void x509cert_req_set_rsa_key( x509_cert_req *ctx, rsa_context *rsa )
+{
+ ctx->rsa = rsa;
+}
+
+int x509cert_req_set_subject_name( x509_cert_req *ctx, char *subject_name )
+{
+ int ret = 0;
+ char *s = subject_name, *c = s;
+ char *end = s + strlen( s );
+ char *oid = NULL;
+ int in_tag = 1;
+ x509_req_name *cur = ctx->subject;
+
+ while( ctx->subject )
+ {
+ cur = ctx->subject;
+ ctx->subject = ctx->subject->next;
+ polarssl_free( cur );
+ }
+
+ while( c <= end )
+ {
+ if( in_tag && *c == '=' )
+ {
+ if( memcmp( s, "CN", 2 ) == 0 && c - s == 2 )
+ oid = OID_AT_CN;
+ else if( memcmp( s, "C", 1 ) == 0 && c - s == 1 )
+ oid = OID_AT_COUNTRY;
+ else if( memcmp( s, "O", 1 ) == 0 && c - s == 1 )
+ oid = OID_AT_ORGANIZATION;
+ else if( memcmp( s, "L", 1 ) == 0 && c - s == 1 )
+ oid = OID_AT_LOCALITY;
+ else if( memcmp( s, "R", 1 ) == 0 && c - s == 1 )
+ oid = OID_PKCS9_EMAIL;
+ else if( memcmp( s, "OU", 2 ) == 0 && c - s == 2 )
+ oid = OID_AT_ORG_UNIT;
+ else if( memcmp( s, "ST", 2 ) == 0 && c - s == 2 )
+ oid = OID_AT_STATE;
+ else
+ {
+ ret = POLARSSL_ERR_X509_WRITE_UNKNOWN_OID;
+ goto exit;
+ }
+
+ s = c + 1;
+ in_tag = 0;
+ }
+
+ if( !in_tag && ( *c == ',' || c == end ) )
+ {
+ if( c - s > 127 )
+ {
+ ret = POLARSSL_ERR_X509_WRITE_BAD_INPUT_DATA;
+ goto exit;
+ }
+
+ if( cur == NULL )
+ {
+ ctx->subject = cur = polarssl_malloc( sizeof(x509_req_name) );
+ }
+ else
+ {
+ cur->next = polarssl_malloc( sizeof(x509_req_name) );
+ cur = cur->next;
+ }
+
+ if( cur == NULL )
+ {
+ ret = POLARSSL_ERR_X509_WRITE_MALLOC_FAILED;
+ goto exit;
+ }
+
+ memset( cur, 0, sizeof(x509_req_name) );
+
+ strncpy( cur->oid, oid, strlen( oid ) );
+ strncpy( cur->name, s, c - s );
+
+ s = c + 1;
+ in_tag = 1;
+ }
+ c++;
+ }
+
+exit:
+
+ return( ret );
+}
+
int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa )
{
int ret;
@@ -41,6 +161,12 @@
c = buf + size - 1;
+ /*
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER -- e
+ * }
+ */
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
@@ -50,6 +176,11 @@
if( c - buf < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
+ /*
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING }
+ */
*--c = 0;
len += 1;
@@ -167,8 +298,8 @@
return( len );
}
-int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
- x509_req_name *req_name, md_type_t md_alg )
+int x509_write_cert_req( x509_cert_req *ctx, unsigned char *buf,
+ size_t size )
{
int ret;
const char *sig_oid;
@@ -178,15 +309,15 @@
unsigned char tmp_buf[2048];
size_t sub_len = 0, pub_len = 0, sig_len = 0;
size_t len = 0;
- x509_req_name *cur = req_name;
+ x509_req_name *cur = ctx->subject;
c = tmp_buf + 2048 - 1;
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, 0 ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
- ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &rsa->E ) );
- ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &rsa->N ) );
+ 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->N ) );
ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
@@ -194,6 +325,11 @@
if( c - tmp_buf < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
+ /*
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL }
+ */
*--c = 0;
pub_len += 1;
@@ -217,21 +353,24 @@
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 ) );
+ /*
+ * 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 ) );
- md( md_info_from_type( md_alg ), c, len, hash );
+ md( md_info_from_type( ctx->md_alg ), c, len, hash );
- rsa_pkcs1_sign( rsa, NULL, NULL, RSA_PRIVATE, md_alg, 0, hash, sig );
+ rsa_pkcs1_sign( ctx->rsa, NULL, NULL, RSA_PRIVATE, ctx->md_alg, 0, hash, sig );
// Generate correct OID
//
- ret = oid_get_oid_by_sig_alg( POLARSSL_PK_RSA, md_alg, &sig_oid );
+ ret = oid_get_oid_by_sig_alg( POLARSSL_PK_RSA, ctx->md_alg, &sig_oid );
c2 = buf + size - 1;
- ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, rsa->len ) );
+ ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, ctx->rsa->len ) );
c2 -= len;
memcpy( c2, c, len );