Added support for writing key_usage extension
diff --git a/include/polarssl/oid.h b/include/polarssl/oid.h
index ebb5bad..025a15f 100644
--- a/include/polarssl/oid.h
+++ b/include/polarssl/oid.h
@@ -228,6 +228,11 @@
#define OID_PKCS5_PBE_SHA1_RC2_CBC OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */
/*
+ * PKCS#8 OIDs
+ */
+#define OID_PKCS9_CSR_EXT_REQ OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */
+
+/*
* PKCS#12 PBE OIDs
*/
#define OID_PKCS12_PBE OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */
diff --git a/include/polarssl/x509write.h b/include/polarssl/x509write.h
index acff33d..aa4d053 100644
--- a/include/polarssl/x509write.h
+++ b/include/polarssl/x509write.h
@@ -29,7 +29,7 @@
#include "config.h"
-#include "rsa.h"
+#include "x509.h"
/**
* \addtogroup x509_module
@@ -80,6 +80,7 @@
rsa_context *rsa;
x509_req_name *subject;
md_type_t md_alg;
+ unsigned char key_usage;
}
x509_csr;
@@ -125,6 +126,15 @@
void x509write_csr_set_md_alg( x509_csr *ctx, md_type_t md_alg );
/**
+ * \brief Set the Key Usage Extension flags
+ * (e.g. KU_DIGITAL_SIGNATURE | KU_KEY_CERT_SIGN)
+ *
+ * \param ctx CSR context to use
+ * \param key_usage key usage bitstring to set
+ */
+void x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage );
+
+/**
* \brief Free the contents of a CSR context
*
* \param ctx CSR context to free
diff --git a/library/x509write.c b/library/x509write.c
index 337f4c2..adeb551 100644
--- a/library/x509write.c
+++ b/library/x509write.c
@@ -148,6 +148,11 @@
return( ret );
}
+void x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage )
+{
+ ctx->key_usage = key_usage;
+}
+
int x509write_pubkey_der( rsa_context *rsa, unsigned char *buf, size_t size )
{
int ret;
@@ -301,13 +306,43 @@
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_len = 0;
+ size_t sub_len = 0, pub_len = 0, sig_len = 0, ext_len = 0;
size_t len = 0;
x509_req_name *cur = ctx->subject;
c = tmp_buf + 2048 - 1;
- ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, 0 ) );
+ /*
+ * 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 ) );
+ 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_OCTET_STRING ) );
+ ASN1_CHK_ADD( ext_len, asn1_write_oid( &c, tmp_buf, OID_KEY_USAGE ) );
+ 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 ) );
+ }
+
+ if( 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_len( &c, tmp_buf, ext_len ) );
+ ASN1_CHK_ADD( ext_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( 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 ) );
+ }
+
+ len += ext_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( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->E ) );