Merge remote-tracking branch 'upstream-public/pr/1109' into mbedtls-1.3
diff --git a/ChangeLog b/ChangeLog
index e7d4f96..2886e0f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,6 +25,16 @@
      causing it to return invalid values. Found by Guido Vranken. #756
    * Include configuration file in md.h, to fix compilation warnings.
      Reported by aaronmdjones in #1001
+   * Correct extraction of signature-type from PK instance in X.509 CRT and CSR
+     writing routines that prevented these functions to work with alternative
+     RSA implementations. Raised by J.B. in the Mbed TLS forum. Fixes #1011.
+   * Don't print X.509 version tag for v1 CRT's, and omit extensions for
+     non-v3 CRT's.
+
+Changes
+   * Extend cert_write example program by options to set the CRT version
+     and the message digest. Further, allow enabling/disabling of authority
+     identifier, subject identifier and basic constraints extensions.
 
 = mbed TLS 1.3.21 branch released 2017-08-10
 
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 446a8e9..19dd0be 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -52,7 +52,7 @@
 
 void x509write_crt_init( x509write_cert *ctx )
 {
-    memset( ctx, 0, sizeof(x509write_cert) );
+    memset( ctx, 0, sizeof( x509write_cert ) );
 
     mpi_init( &ctx->serial );
     ctx->version = X509_CRT_VERSION_3;
@@ -66,7 +66,7 @@
     asn1_free_named_data_list( &ctx->issuer );
     asn1_free_named_data_list( &ctx->extensions );
 
-    polarssl_zeroize( ctx, sizeof(x509write_cert) );
+    polarssl_zeroize( ctx, sizeof( x509write_cert ) );
 }
 
 void x509write_crt_set_version( x509write_cert *ctx, int version )
@@ -141,10 +141,10 @@
 {
     int ret;
     unsigned char buf[9];
-    unsigned char *c = buf + sizeof(buf);
+    unsigned char *c = buf + sizeof( buf );
     size_t len = 0;
 
-    memset( buf, 0, sizeof(buf) );
+    memset( buf, 0, sizeof( buf ) );
 
     if( is_ca && max_pathlen > 127 )
         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
@@ -164,7 +164,7 @@
 
     return x509write_crt_set_extension( ctx, OID_BASIC_CONSTRAINTS,
                                         OID_SIZE( OID_BASIC_CONSTRAINTS ),
-                                        0, buf + sizeof(buf) - len, len );
+                                        0, buf + sizeof( buf ) - len, len );
 }
 
 #if defined(POLARSSL_SHA1_C)
@@ -172,14 +172,14 @@
 {
     int ret;
     unsigned char buf[POLARSSL_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
-    unsigned char *c = buf + sizeof(buf);
+    unsigned char *c = buf + sizeof( buf );
     size_t len = 0;
 
-    memset( buf, 0, sizeof(buf) );
+    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;
+    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 ) );
@@ -187,21 +187,21 @@
 
     return x509write_crt_set_extension( ctx, OID_SUBJECT_KEY_IDENTIFIER,
                                         OID_SIZE( OID_SUBJECT_KEY_IDENTIFIER ),
-                                        0, buf + sizeof(buf) - len, len );
+                                        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);
+    unsigned char *c = buf + sizeof( buf );
     size_t len = 0;
 
-    memset( buf, 0, sizeof(buf) );
+    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;
+    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 ) );
@@ -213,7 +213,7 @@
 
     return x509write_crt_set_extension( ctx, OID_AUTHORITY_KEY_IDENTIFIER,
                                    OID_SIZE( OID_AUTHORITY_KEY_IDENTIFIER ),
-                                   0, buf + sizeof(buf) - len, len );
+                                   0, buf + sizeof( buf ) - len, len );
 }
 #endif /* POLARSSL_SHA1_C */
 
@@ -308,9 +308,15 @@
     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 )
+
+    /* There's no direct way of extracting a signature algorithm
+     * (represented as an element of pk_type_t) from a PK instance. */
+    if( pk_can_do( ctx->issuer_key, POLARSSL_PK_RSA ) )
+        pk_alg = POLARSSL_PK_RSA;
+    else if( pk_can_do( ctx->issuer_key, POLARSSL_PK_ECDSA ) )
         pk_alg = POLARSSL_PK_ECDSA;
+    else
+        return( POLARSSL_ERR_X509_INVALID_ALG );
 
     if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
                                         &sig_oid, &sig_oid_len ) ) != 0 )
@@ -321,13 +327,19 @@
     /*
      *  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 ) );
+
+    /* Only for v3 */
+    if( ctx->version == X509_CRT_VERSION_3 )
+    {
+        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
@@ -379,16 +391,20 @@
     /*
      *  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 ) );
+
+    if( ctx->version != X509_CRT_VERSION_1 )
+    {
+        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 ) );
+                                       ASN1_SEQUENCE ) );
 
     /*
      * Make signature
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index 1b3d2f5..7418882 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -51,7 +51,7 @@
 
 void x509write_csr_init( x509write_csr *ctx )
 {
-    memset( ctx, 0, sizeof(x509write_csr) );
+    memset( ctx, 0, sizeof( x509write_csr ) );
 }
 
 void x509write_csr_free( x509write_csr *ctx )
@@ -59,7 +59,7 @@
     asn1_free_named_data_list( &ctx->subject );
     asn1_free_named_data_list( &ctx->extensions );
 
-    polarssl_zeroize( ctx, sizeof(x509write_csr) );
+    polarssl_zeroize( ctx, sizeof( x509write_csr ) );
 }
 
 void x509write_csr_set_md_alg( x509write_csr *ctx, md_type_t md_alg )
@@ -195,13 +195,20 @@
      */
     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,
+                         f_rng, p_rng ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( pk_can_do( ctx->key, POLARSSL_PK_RSA ) )
+        pk_alg = POLARSSL_PK_RSA;
+    else if( pk_can_do( ctx->key, POLARSSL_PK_ECDSA ) )
+        pk_alg = POLARSSL_PK_ECDSA;
+    else
+        return( POLARSSL_ERR_X509_INVALID_ALG );
+
+    if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
                                         &sig_oid, &sig_oid_len ) ) != 0 )
     {
         return( ret );
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 290eebc..1246158 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -54,6 +54,7 @@
 #include "polarssl/x509_csr.h"
 #include "polarssl/entropy.h"
 #include "polarssl/ctr_drbg.h"
+#include "polarssl/md.h"
 #include "polarssl/error.h"
 
 #include <stdio.h>
@@ -86,6 +87,11 @@
 #define DFL_MAX_PATHLEN         -1
 #define DFL_KEY_USAGE           0
 #define DFL_NS_CERT_TYPE        0
+#define DFL_VERSION             3
+#define DFL_AUTH_IDENT          1
+#define DFL_SUBJ_IDENT          1
+#define DFL_CONSTRAINTS         1
+#define DFL_DIGEST              POLARSSL_MD_SHA256
 
 #define USAGE \
     "\n usage: cert_write param=<>...\n"                \
@@ -112,6 +118,20 @@
     "    not_after=%%s        default: 20301231235959\n"\
     "    is_ca=%%d            default: 0 (disabled)\n"  \
     "    max_pathlen=%%d      default: -1 (none)\n"     \
+    "    md=%%s               default: SHA256\n"        \
+    "                        Supported values:\n"       \
+    "                        MD5, SHA1, SHA256, SHA512\n"\
+    "    version=%%d           default: 3\n"            \
+    "                        Possible values: 1, 2, 3\n"\
+    "    subject_identifier   default: 1\n"             \
+    "                        Possible values: 0, 1\n"   \
+    "                        (Considered for v3 only)\n"\
+    "    authority_identifier default: 1\n"             \
+    "                        Possible values: 0, 1\n"   \
+    "                        (Considered for v3 only)\n"\
+    "    basic_constraints    default: 1\n"             \
+    "                        Possible values: 0, 1\n"   \
+    "                        (Considered for v3 only)\n"\
     "    key_usage=%%s        default: (empty)\n"       \
     "                        Comma-separated-list of values:\n"     \
     "                          digital_signature\n"     \
@@ -121,6 +141,7 @@
     "                          key_agreement\n"         \
     "                          key_certificate_sign\n"  \
     "                          crl_sign\n"              \
+    "                        (Considered for v3 only)\n"\
     "    ns_cert_type=%%s     default: (empty)\n"       \
     "                        Comma-separated-list of values:\n"     \
     "                          ssl_client\n"            \
@@ -152,6 +173,11 @@
     int selfsign;               /* selfsign the certificate             */
     int is_ca;                  /* is a CA certificate                  */
     int max_pathlen;            /* maximum CA path length               */
+    int authority_identifier;   /* add authority identifier to CRT      */
+    int subject_identifier;     /* add subject identifier to CRT        */
+    int basic_constraints;      /* add basic constraints ext to CRT     */
+    int version;                /* CRT version                          */
+    md_type_t md;               /* Hash used for signing                */
     unsigned char key_usage;    /* key usage flags                      */
     unsigned char ns_cert_type; /* NS cert type                         */
 } opt;
@@ -246,6 +272,11 @@
     opt.max_pathlen         = DFL_MAX_PATHLEN;
     opt.key_usage           = DFL_KEY_USAGE;
     opt.ns_cert_type        = DFL_NS_CERT_TYPE;
+    opt.version             = DFL_VERSION - 1;
+    opt.md                  = DFL_DIGEST;
+    opt.subject_identifier   = DFL_SUBJ_IDENT;
+    opt.authority_identifier = DFL_AUTH_IDENT;
+    opt.basic_constraints    = DFL_CONSTRAINTS;
 
     for( i = 1; i < argc; i++ )
     {
@@ -289,23 +320,88 @@
         {
             opt.serial = q;
         }
+        else if( strcmp( p, "authority_identifier" ) == 0 )
+        {
+            opt.authority_identifier = atoi( q );
+            if( opt.authority_identifier != 0 &&
+                opt.authority_identifier != 1 )
+            {
+                polarssl_printf( "Invalid argument for option %s\n", p );
+                goto usage;
+            }
+        }
+        else if( strcmp( p, "subject_identifier" ) == 0 )
+        {
+            opt.subject_identifier = atoi( q );
+            if( opt.subject_identifier != 0 &&
+                opt.subject_identifier != 1 )
+            {
+                polarssl_printf( "Invalid argument for option %s\n", p );
+                goto usage;
+            }
+        }
+        else if( strcmp( p, "basic_constraints" ) == 0 )
+        {
+            opt.basic_constraints = atoi( q );
+            if( opt.basic_constraints != 0 &&
+                opt.basic_constraints != 1 )
+            {
+                polarssl_printf( "Invalid argument for option %s\n", p );
+                goto usage;
+            }
+        }
+        else if( strcmp( p, "md" ) == 0 )
+        {
+            if( strcmp( q, "SHA1" ) == 0 )
+                opt.md = POLARSSL_MD_SHA1;
+            else if( strcmp( q, "SHA256" ) == 0 )
+                opt.md = POLARSSL_MD_SHA256;
+            else if( strcmp( q, "SHA512" ) == 0 )
+                opt.md = POLARSSL_MD_SHA512;
+            else if( strcmp( q, "MD5" ) == 0 )
+                opt.md = POLARSSL_MD_MD5;
+            else
+            {
+                polarssl_printf( "Invalid argument for option %s\n", p );
+                goto usage;
+            }
+        }
+        else if( strcmp( p, "version" ) == 0 )
+        {
+            opt.version = atoi( q );
+            if( opt.version < 1 || opt.version > 3 )
+            {
+                polarssl_printf( "Invalid argument for option %s\n", p );
+                goto usage;
+            }
+            opt.version--;
+        }
         else if( strcmp( p, "selfsign" ) == 0 )
         {
             opt.selfsign = atoi( q );
             if( opt.selfsign < 0 || opt.selfsign > 1 )
+            {
+                polarssl_printf( "Invalid argument for option %s\n", p );
                 goto usage;
+            }
         }
         else if( strcmp( p, "is_ca" ) == 0 )
         {
             opt.is_ca = atoi( q );
             if( opt.is_ca < 0 || opt.is_ca > 1 )
+            {
+                polarssl_printf( "Invalid argument for option %s\n", p );
                 goto usage;
+            }
         }
         else if( strcmp( p, "max_pathlen" ) == 0 )
         {
             opt.max_pathlen = atoi( q );
             if( opt.max_pathlen < -1 || opt.max_pathlen > 127 )
+            {
+                polarssl_printf( "Invalid argument for option %s\n", p );
                 goto usage;
+            }
         }
         else if( strcmp( p, "key_usage" ) == 0 )
         {
@@ -329,7 +425,10 @@
                 else if( strcmp( q, "crl_sign" ) == 0 )
                     opt.key_usage |= KU_CRL_SIGN;
                 else
+                {
+                    polarssl_printf( "Invalid argument for option %s\n", p );
                     goto usage;
+                }
 
                 q = r;
             }
@@ -356,7 +455,10 @@
                 else if( strcmp( q, "object_signing_ca" ) == 0 )
                     opt.ns_cert_type |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
                 else
+                {
+                    polarssl_printf( "Invalid argument for option %s\n", p );
                     goto usage;
+                }
 
                 q = r;
             }
@@ -379,7 +481,8 @@
                                strlen( pers ) ) ) != 0 )
     {
         polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  ctr_drbg_init returned %d - %s\n", ret, buf );
+        polarssl_printf( " failed\n  !  ctr_drbg_init "
+                         "returned %d - %s\n", ret, buf );
         goto exit;
     }
 
@@ -393,7 +496,8 @@
     if( ( ret = mpi_read_string( &serial, 10, opt.serial ) ) != 0 )
     {
         polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  mpi_read_string returned -0x%02x - %s\n\n", -ret, buf );
+        polarssl_printf( " failed\n  !  mpi_read_string "
+                         "returned -0x%04x - %s\n\n", -ret, buf );
         goto exit;
     }
 
@@ -412,7 +516,8 @@
         if( ( ret = x509_crt_parse_file( &issuer_crt, opt.issuer_crt ) ) != 0 )
         {
             polarssl_strerror( ret, buf, 1024 );
-            polarssl_printf( " failed\n  !  x509_crt_parse_file returned -0x%02x - %s\n\n", -ret, buf );
+            polarssl_printf( " failed\n  !  x509_crt_parse_file returned "
+                             "-0x%04x - %s\n\n", -ret, buf );
             goto exit;
         }
 
@@ -421,7 +526,8 @@
         if( ret < 0 )
         {
             polarssl_strerror( ret, buf, 1024 );
-            polarssl_printf( " failed\n  !  x509_dn_gets returned -0x%02x - %s\n\n", -ret, buf );
+            polarssl_printf( " failed\n  !  x509_dn_gets returned "
+                             "-0x%04x - %s\n\n", -ret, buf );
             goto exit;
         }
 
@@ -444,7 +550,8 @@
         if( ( ret = x509_csr_parse_file( &csr, opt.request_file ) ) != 0 )
         {
             polarssl_strerror( ret, buf, 1024 );
-            polarssl_printf( " failed\n  !  x509_csr_parse_file returned -0x%02x - %s\n\n", -ret, buf );
+            polarssl_printf( " failed\n  !  x509_csr_parse_file returned "
+                             "-0x%04x - %s\n\n", -ret, buf );
             goto exit;
         }
 
@@ -453,7 +560,8 @@
         if( ret < 0 )
         {
             polarssl_strerror( ret, buf, 1024 );
-            polarssl_printf( " failed\n  !  x509_dn_gets returned -0x%02x - %s\n\n", -ret, buf );
+            polarssl_printf( " failed\n  !  x509_dn_gets returned "
+                             "-0x%04x - %s\n\n", -ret, buf );
             goto exit;
         }
 
@@ -477,7 +585,8 @@
         if( ret != 0 )
         {
             polarssl_strerror( ret, buf, 1024 );
-            polarssl_printf( " failed\n  !  pk_parse_keyfile returned -0x%02x - %s\n\n", -ret, buf );
+            polarssl_printf( " failed\n  !  pk_parse_keyfile returned "
+                             "-0x%04x - %s\n\n", -ret, buf );
             goto exit;
         }
 
@@ -492,7 +601,8 @@
     if( ret != 0 )
     {
         polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  pk_parse_keyfile returned -x%02x - %s\n\n", -ret, buf );
+        polarssl_printf( " failed\n  !  pk_parse_keyfile returned "
+                         "-x%02x - %s\n\n", -ret, buf );
         goto exit;
     }
 
@@ -506,7 +616,8 @@
             mpi_cmp_mpi( &pk_rsa( issuer_crt.pk )->E,
                          &pk_rsa( *issuer_key )->E ) != 0 )
         {
-            polarssl_printf( " failed\n  !  issuer_key does not match issuer certificate\n\n" );
+            polarssl_printf( " failed\n  !  issuer_key does not match "
+                             "issuer certificate\n\n" );
             ret = -1;
             goto exit;
         }
@@ -526,28 +637,35 @@
     /*
      * 1.0. Check the names for validity
      */
-    if( ( ret = x509write_crt_set_subject_name( &crt, opt.subject_name ) ) != 0 )
+    if( ( ret = x509write_crt_set_subject_name( &crt,
+                                                opt.subject_name ) ) != 0 )
     {
         polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  x509write_crt_set_subject_name returned -0x%02x - %s\n\n", -ret, buf );
+        polarssl_printf( " failed\n  !  x509write_crt_set_subject_name returned"
+                         " -0x%04x - %s\n\n", -ret, buf );
         goto exit;
     }
 
     if( ( ret = x509write_crt_set_issuer_name( &crt, opt.issuer_name ) ) != 0 )
     {
         polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  x509write_crt_set_issuer_name returned -0x%02x - %s\n\n", -ret, buf );
+        polarssl_printf( " failed\n  !  x509write_crt_set_issuer_name returned "
+                         "-0x%04x - %s\n\n", -ret, buf );
         goto exit;
     }
 
     polarssl_printf( "  . Setting certificate values ..." );
     fflush( stdout );
 
+    x509write_crt_set_version( &crt, opt.version );
+    x509write_crt_set_md_alg( &crt, opt.md );
+
     ret = x509write_crt_set_serial( &crt, &serial );
     if( ret != 0 )
     {
         polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  x509write_crt_set_serial returned -0x%02x - %s\n\n", -ret, buf );
+        polarssl_printf( " failed\n  !  x509write_crt_set_serial returned "
+                         "-0x%04x - %s\n\n", -ret, buf );
         goto exit;
     }
 
@@ -555,55 +673,72 @@
     if( ret != 0 )
     {
         polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  x509write_crt_set_validity returned -0x%02x - %s\n\n", -ret, buf );
+        polarssl_printf( " failed\n  !  x509write_crt_set_validity returned "
+                         "-0x%04x - %s\n\n", -ret, buf );
         goto exit;
     }
 
     polarssl_printf( " ok\n" );
 
-    polarssl_printf( "  . Adding the Basic Constraints extension ..." );
-    fflush( stdout );
-
-    ret = x509write_crt_set_basic_constraints( &crt, opt.is_ca,
-                                               opt.max_pathlen );
-    if( ret != 0 )
+    if( opt.version == 3 && opt.basic_constraints )
     {
-        polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  x509write_crt_set_basic_contraints returned -0x%02x - %s\n\n", -ret, buf );
-        goto exit;
-    }
+        polarssl_printf( "  . Adding the Basic Constraints extension ..." );
+        fflush( stdout );
 
-    polarssl_printf( " ok\n" );
+        ret = x509write_crt_set_basic_constraints( &crt, opt.is_ca,
+                                                           opt.max_pathlen );
+        if( ret != 0 )
+        {
+            polarssl_strerror( ret, buf, 1024 );
+            polarssl_printf( " failed\n  !  x509write_crt_set_basic_contraints "
+                             "returned -0x%04x - %s\n\n", -ret, buf );
+            goto exit;
+        }
+
+        polarssl_printf( " ok\n" );
+    }
 
 #if defined(POLARSSL_SHA1_C)
-    polarssl_printf( "  . Adding the Subject Key Identifier ..." );
-    fflush( stdout );
-
-    ret = x509write_crt_set_subject_key_identifier( &crt );
-    if( ret != 0 )
+    if( opt.version == 3 && opt.subject_identifier )
     {
-        polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  x509write_crt_set_subject_key_identifier returned -0x%02x - %s\n\n", -ret, buf );
-        goto exit;
+        polarssl_printf( "  . Adding the Subject Key Identifier ..." );
+        fflush( stdout );
+
+        ret = x509write_crt_set_subject_key_identifier( &crt );
+        if( ret != 0 )
+        {
+            polarssl_strerror( ret, buf, 1024 );
+            polarssl_printf( " failed\n  !  x509write_crt_set_subject"
+                            "_key_identifier returned -0x%04x - %s\n\n",
+                            -ret, buf );
+            goto exit;
+        }
+
+        polarssl_printf( " ok\n" );
     }
 
-    polarssl_printf( " ok\n" );
-
-    polarssl_printf( "  . Adding the Authority Key Identifier ..." );
-    fflush( stdout );
-
-    ret = x509write_crt_set_authority_key_identifier( &crt );
-    if( ret != 0 )
+    if( opt.version == X509_CRT_VERSION_3 &&
+        opt.authority_identifier != 0 )
     {
-        polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  x509write_crt_set_authority_key_identifier returned -0x%02x - %s\n\n", -ret, buf );
-        goto exit;
-    }
+        polarssl_printf( "  . Adding the Authority Key Identifier ..." );
+        fflush( stdout );
 
-    polarssl_printf( " ok\n" );
+        ret = x509write_crt_set_authority_key_identifier( &crt );
+        if( ret != 0 )
+        {
+            polarssl_strerror( ret, buf, 1024 );
+            polarssl_printf( " failed\n  !  x509write_crt_set_authority_"
+                            "key_identifier returned -0x%04x - %s\n\n",
+                            -ret, buf );
+            goto exit;
+        }
+
+        polarssl_printf( " ok\n" );
+    }
 #endif /* POLARSSL_SHA1_C */
 
-    if( opt.key_usage )
+    if( opt.version == X509_CRT_VERSION_3 &&
+        opt.key_usage != 0 )
     {
         polarssl_printf( "  . Adding the Key Usage extension ..." );
         fflush( stdout );
@@ -612,14 +747,16 @@
         if( ret != 0 )
         {
             polarssl_strerror( ret, buf, 1024 );
-            polarssl_printf( " failed\n  !  x509write_crt_set_key_usage returned -0x%02x - %s\n\n", -ret, buf );
+            polarssl_printf( " failed\n  !  x509write_crt_set_key_usage "
+                             "returned -0x%04x - %s\n\n", -ret, buf );
             goto exit;
         }
 
         polarssl_printf( " ok\n" );
     }
 
-    if( opt.ns_cert_type )
+    if( opt.version == X509_CRT_VERSION_3 &&
+        opt.ns_cert_type != 0 )
     {
         polarssl_printf( "  . Adding the NS Cert Type extension ..." );
         fflush( stdout );
@@ -628,7 +765,8 @@
         if( ret != 0 )
         {
             polarssl_strerror( ret, buf, 1024 );
-            polarssl_printf( " failed\n  !  x509write_crt_set_ns_cert_type returned -0x%02x - %s\n\n", -ret, buf );
+            polarssl_printf( " failed\n  !  x509write_crt_set_ns_cert_type "
+                             "returned -0x%04x - %s\n\n", -ret, buf );
             goto exit;
         }
 
@@ -645,7 +783,8 @@
                                    ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
         polarssl_strerror( ret, buf, 1024 );
-        polarssl_printf( " failed\n  !  write_certifcate -0x%02x - %s\n\n", -ret, buf );
+        polarssl_printf( " failed\n  !  write_certifcate returned "
+                         "-0x%04x - %s\n\n", -ret, buf );
         goto exit;
     }
 
diff --git a/tests/data_files/server1.cert_type_noauthid.crt b/tests/data_files/server1.cert_type_noauthid.crt
new file mode 100644
index 0000000..3c0f237
--- /dev/null
+++ b/tests/data_files/server1.cert_type_noauthid.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDMTCCAhmgAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
+A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
+uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
+d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
+CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
+lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
+bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
+oz8wPTAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAR
+BglghkgBhvhCAQEEBAMCAEAwDQYJKoZIhvcNAQEFBQADggEBABNT+r+6vvlpjtyz
+mewrGOKPt5iwb8w2aReJ0AWuyQzTiduN26MhXq93cXHV0pHj2rD7MfiBEwBSWnf9
+FcxkE0g77GVyM9Vs9Uy/MspIqOce7JD0c36G4EI8lYce2TYwQLE9CGNl+LDxqkLy
+prijXBl/FaD+IO/SNMr3VVnfFEZqPUxg+BSTaGgD+52Z7B4nPP0xGPjlW367RGDv
+9dIkr1thve2WOeC9ixxl9K/864I7/0GdbgKSf77xl3/5vnQUOY7kugRvkvxWIgHS
+HNVnmEN2I2Nb0M8lQNF1sFDbpFwVbh9CkBF5LJNesy0VWd67Ho6EntPEb7vBFF/x
+jz0b2l4=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/data_files/server1.key_usage_noauthid.crt b/tests/data_files/server1.key_usage_noauthid.crt
new file mode 100644
index 0000000..2223807
--- /dev/null
+++ b/tests/data_files/server1.key_usage_noauthid.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDLjCCAhagAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
+A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
+uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
+d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
+CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
+lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
+bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
+ozwwOjAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAO
+BgNVHQ8BAf8EBAMCAeAwDQYJKoZIhvcNAQEFBQADggEBAJZRIISo4+rDvHXXaS43
+shfSkyJyur588mNJFzty1WVfhaIkwjMIGHeGlHS29fwgPsBUgelZ3Qv3J7wsm42+
+3BwQet0l36FIBIJtFhcrTGlaCFUo/5bZJUPGgiOFB9ec/8lOszVlX8cH34UimWqg
+q2wXRGoXWPbuRnUWlJhI2bAv5ri9Mt7Rs4nK4wyS1ZjC8ByXMn4tk3yMjkUEqu0o
+37zoQiF+FJApu0eTKK5goA2hisyfCX9eJMppAbcyvJwoj/AmiBkXW8J3kEMJtLmZ
+VoxXYknnXumxBLxUrGuamR/3cmbaJHIHE1Dqox7hB+9miyp4lue1/uXHCocGAIeF
+JTo=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/data_files/server1.noauthid.crt b/tests/data_files/server1.noauthid.crt
new file mode 100644
index 0000000..99c004f
--- /dev/null
+++ b/tests/data_files/server1.noauthid.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDHjCCAgagAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
+A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
+uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
+d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
+CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
+lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
+bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
+oywwKjAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAN
+BgkqhkiG9w0BAQUFAAOCAQEAUMDKviuchRc4ICoVwi9LFyfQjxFQLgjnX1UYSqc5
+UptiJsDpbJ+TMbOhNBs7YRV7ju61J33ax1fqgcFWkc2M2Vsqzz9+3zJlQoQuOLxH
+5C6v5/rhUEV9HMy3K5SIa/BVem9osWvMwDnB8g5k3wCZAnOuFcT6ttvzRqz6Oh9d
+avozrYHsATzPXBal41Gf95cNVcJ1pn/JgE4EOijMqmAPldVbCqfXLl6TB0nJS6dm
+q9z73DGrVQlOwmCVI+qD2POJI67LuQ0g6Y0WVMxsWilMppt+UrEknMzk4O4qOaUs
+1B20vI/bN4XPDnw58psazdoBxFL+fAk5MbTNKETNHjBsIg==
+-----END CERTIFICATE-----
diff --git a/tests/data_files/server1.v1.crt b/tests/data_files/server1.v1.crt
index 0a4b2a5..b13be43 100644
--- a/tests/data_files/server1.v1.crt
+++ b/tests/data_files/server1.v1.crt
@@ -1,18 +1,18 @@
 -----BEGIN CERTIFICATE-----
-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
+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
 -----END CERTIFICATE-----
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index 66f0993..a8e7f25 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -44,19 +44,35 @@
 
 Certificate write check Server1 SHA1
 depends_on:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_DES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:0:0:-1:"data_files/server1.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:0:0:1:-1:"data_files/server1.crt":0
 
 Certificate write check Server1 SHA1, key_usage
 depends_on:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_DES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION | KU_KEY_ENCIPHERMENT:0:-1:"data_files/server1.key_usage.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION | KU_KEY_ENCIPHERMENT:0:1:-1:"data_files/server1.key_usage.crt":0
 
 Certificate write check Server1 SHA1, ns_cert_type
 depends_on:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_DES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:0:NS_CERT_TYPE_SSL_SERVER:-1:"data_files/server1.cert_type.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:0:NS_CERT_TYPE_SSL_SERVER:1:-1:"data_files/server1.cert_type.crt":0
 
 Certificate write check Server1 SHA1, version 1
 depends_on:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_DES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:0:0:X509_CRT_VERSION_1:"data_files/server1.v1.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:0:0:1:X509_CRT_VERSION_1:"data_files/server1.v1.crt":0
+
+Certificate write check Server1 SHA1, RSA_ALT
+depends_on:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_DES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:0:0:0:-1:"data_files/server1.noauthid.crt":0
+
+Certificate write check Server1 SHA1, RSA_ALT, key_usage
+depends_on:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_DES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION | KU_KEY_ENCIPHERMENT:0:0:-1:"data_files/server1.key_usage_noauthid.crt":0
+
+Certificate write check Server1 SHA1, RSA_ALT, ns_cert_type
+depends_on:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_DES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:0:NS_CERT_TYPE_SSL_SERVER:0:-1:"data_files/server1.cert_type_noauthid.crt":0
+
+Certificate write check Server1 SHA1, RSA_ALT, version 1
+depends_on:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_DES_C:POLARSSL_CIPHER_MODE_CBC:POLARSSL_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":POLARSSL_MD_SHA1:0:0:0:X509_CRT_VERSION_1:"data_files/server1.v1.crt":0
 
 X509 String to Names #1
 x509_string_to_names:"C=NL,O=Offspark\, Inc., OU=PolarSSL":"C=NL, O=Offspark, Inc., OU=PolarSSL":0
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index 825a593..1cfa402 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -3,6 +3,30 @@
 #include "polarssl/x509_csr.h"
 #include "polarssl/pem.h"
 #include "polarssl/oid.h"
+#include "polarssl/rsa.h"
+
+#if defined(POLARSSL_RSA_C)
+int rsa_decrypt_func( void *ctx, int mode, size_t *olen,
+                       const unsigned char *input, unsigned char *output,
+                       size_t output_max_len )
+{
+    return( rsa_pkcs1_decrypt( (rsa_context *) ctx, NULL, NULL, mode, olen,
+                               input, output, output_max_len ) );
+}
+int rsa_sign_func( void *ctx,
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                   int mode, md_type_t md_alg, unsigned int hashlen,
+                   const unsigned char *hash, unsigned char *sig )
+{
+    return( rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, mode,
+                            md_alg, hashlen, hash, sig ) );
+}
+size_t rsa_key_len_func( void *ctx )
+{
+    return( ((const rsa_context *) ctx)->len );
+}
+#endif /* POLARSSL_RSA_C */
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -75,10 +99,12 @@
                      char *subject_name, char *issuer_key_file,
                      char *issuer_pwd, char *issuer_name,
                      char *serial_str, char *not_before, char *not_after,
-                     int md_type, int key_usage, int cert_type, int ver,
-                     char *cert_check_file )
+                     int md_type, int key_usage, int cert_type, int auth_ident,
+                     int ver, char *cert_check_file, int rsa_alt )
 {
-    pk_context subject_key, issuer_key;
+    pk_context subject_key, issuer_key, issuer_key_alt;
+    pk_context *key = &issuer_key;
+
     x509write_cert crt;
     unsigned char buf[4096];
     unsigned char check_buf[5000];
@@ -93,14 +119,29 @@
     mpi_init( &serial );
     pk_init( &subject_key );
     pk_init( &issuer_key );
+    pk_init( &issuer_key_alt );
+
+    x509write_crt_init( &crt );
 
     TEST_ASSERT( pk_parse_keyfile( &subject_key, subject_key_file,
                                          subject_pwd ) == 0 );
     TEST_ASSERT( pk_parse_keyfile( &issuer_key, issuer_key_file,
                                          issuer_pwd ) == 0 );
+
+    /* For RSA PK contexts, create a copy as an alternative RSA context. */
+    if( rsa_alt == 1 && pk_get_type( &issuer_key ) == POLARSSL_PK_RSA )
+    {
+        TEST_ASSERT( pk_init_ctx_rsa_alt( &issuer_key_alt,
+                                          pk_rsa( issuer_key ),
+                                          rsa_decrypt_func,
+                                          rsa_sign_func,
+                                          rsa_key_len_func ) == 0 );
+
+        key = &issuer_key_alt;
+    }
+
     TEST_ASSERT( mpi_read_string( &serial, 10, serial_str ) == 0 );
 
-    x509write_crt_init( &crt );
     if( ver != -1 )
         x509write_crt_set_version( &crt, ver );
     TEST_ASSERT( x509write_crt_set_serial( &crt, &serial ) == 0 );
@@ -110,20 +151,21 @@
     TEST_ASSERT( x509write_crt_set_issuer_name( &crt, issuer_name ) == 0 );
     TEST_ASSERT( x509write_crt_set_subject_name( &crt, subject_name ) == 0 );
     x509write_crt_set_subject_key( &crt, &subject_key );
-    x509write_crt_set_issuer_key( &crt, &issuer_key );
+    x509write_crt_set_issuer_key( &crt, key );
 
     if( crt.version >= X509_CRT_VERSION_3 )
     {
         TEST_ASSERT( x509write_crt_set_basic_constraints( &crt, 0, 0 ) == 0 );
         TEST_ASSERT( x509write_crt_set_subject_key_identifier( &crt ) == 0 );
-        TEST_ASSERT( x509write_crt_set_authority_key_identifier( &crt ) == 0 );
+        if( auth_ident != 0 )
+            TEST_ASSERT( x509write_crt_set_authority_key_identifier( &crt ) == 0 );
         if( key_usage != 0 )
             TEST_ASSERT( x509write_crt_set_key_usage( &crt, key_usage ) == 0 );
         if( cert_type != 0 )
             TEST_ASSERT( x509write_crt_set_ns_cert_type( &crt, cert_type ) == 0 );
     }
 
-    ret = x509write_crt_pem( &crt, buf, sizeof(buf),
+    ret = x509write_crt_pem( &crt, buf, sizeof( buf ),
                              rnd_pseudo_rand, &rnd_info );
     TEST_ASSERT( ret == 0 );
 
@@ -131,8 +173,8 @@
 
     f = fopen( cert_check_file, "r" );
     TEST_ASSERT( f != NULL );
-    olen = fread( check_buf, 1, sizeof(check_buf), f );
-    TEST_ASSERT( olen < sizeof(check_buf) );
+    olen = fread( check_buf, 1, sizeof( check_buf ), f );
+    TEST_ASSERT( olen < sizeof( check_buf ) );
     fclose( f );
 
     TEST_ASSERT( olen >= pem_len - 1 );
@@ -152,6 +194,7 @@
 exit:
     x509write_crt_free( &crt );
     pk_free( &issuer_key );
+    pk_free( &issuer_key_alt );
     pk_free( &subject_key );
     mpi_free( &serial );
 }