Bug 324744, add gen of policy extns to certutil, second of 3 patches
authorneil.williams%sun.com
Fri, 07 Sep 2007 18:45:53 +0000
changeset 8038 6dab51ba0679e378a6d9ebd5419092b637f70cd9
parent 8037 1887266437e0d56ab6286b0b185272f561e1d1ff
child 8039 ca808502110e5173fdaa2ce5d3983b243d34a1bf
push idunknown
push userunknown
push dateunknown
bugs324744
Bug 324744, add gen of policy extns to certutil, second of 3 patches r=julien
security/nss/cmd/certutil/certext.c
security/nss/cmd/certutil/certutil.c
security/nss/lib/certdb/cert.h
security/nss/lib/certdb/polcyxtn.c
security/nss/lib/certdb/xconst.c
security/nss/lib/nss/nss.def
security/nss/lib/ssl/derive.c
security/nss/lib/util/seccomon.h
security/nss/lib/util/secoid.c
security/nss/lib/util/secoidt.h
--- a/security/nss/cmd/certutil/certext.c
+++ b/security/nss/cmd/certutil/certext.c
@@ -52,21 +52,21 @@
 
 #include "secutil.h"
 
 #if defined(XP_UNIX)
 #include <unistd.h>
 #endif
 
 #include "cert.h"
+#include "prprf.h"
+#include "certutil.h"
 
 #define GEN_BREAK(e) rv=e; break;
 
-extern char *progName;
-
 static char *
 Gets_s(char *buff, size_t size) {
     char *str;
     
     if (buff == NULL || size < 1) {
         PORT_Assert(0);
         return NULL;
     }
@@ -90,39 +90,51 @@ Gets_s(char *buff, size_t size) {
                 buff[len - 2] = '\0';
         }
     } else {
         buff[0] = '\0';
     }
     return str;
 }
 
+
+static SECStatus
+PrintChoicesAndGetAnswer(char* str, char* rBuff, int rSize)
+{
+    fprintf(stdout, str);
+    fprintf(stdout, " > ");
+    fflush (stdout);
+    if (Gets_s(rBuff, rSize) == NULL) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
+    return SECSuccess;
+}
+
 static CERTGeneralName *
 GetGeneralName (PRArenaPool *arena)
 {
     CERTGeneralName *namesList = NULL;
     CERTGeneralName *current;
     CERTGeneralName *tail = NULL;
     SECStatus rv = SECSuccess;
     int intValue;
     char buffer[512];
     void *mark;
 
     PORT_Assert (arena);
     mark = PORT_ArenaMark (arena);
     do {
-        puts ("\nSelect one of the following general name type: \n");
-        puts ("\t1 - instance of other name\n\t2 - rfc822Name\n\t3 - "
-              "dnsName\n");
-        puts ("\t4 - x400Address\n\t5 - directoryName\n\t6 - ediPartyName\n");
-        puts ("\t7 - uniformResourceidentifier\n\t8 - ipAddress\n\t9 - "
-              "registerID\n");
-        puts ("\tAny other number to finish\n\t\tChoice:");
-        if (Gets_s (buffer, sizeof(buffer)) == NULL) {
-            PORT_SetError(SEC_ERROR_INPUT_LEN);
+        if (PrintChoicesAndGetAnswer(
+                "\nSelect one of the following general name type: \n"
+                "\t1 - instance of other name\n\t2 - rfc822Name\n\t3 - dnsName\n"
+                "\t4 - x400Address\n\t5 - directoryName\n\t6 - ediPartyName\n"
+                "\t7 - uniformResourceidentifier\n\t8 - ipAddress\n\t9 - registerID\n"
+                "\tAny other number to finish\n\t\tChoice:",
+                buffer, sizeof(buffer)) == SECFailure) {
             GEN_BREAK (SECFailure);
         }
         intValue = PORT_Atoi (buffer);
         /*
          * Should use ZAlloc instead of Alloc to avoid problem with garbage
          * initialized pointers in CERT_CopyName
          */
         if (intValue >= certOtherName && intValue <= certRegisterID) {
@@ -255,41 +267,40 @@ AddKeyUsage (void *extHandle)
 {
     SECItem bitStringValue;
     unsigned char keyUsage = 0x0;
     char buffer[5];
     int value;
     PRBool yesNoAns;
 
     while (1) {
-        fprintf(stdout, "%-25s 0 - Digital Signature\n", "");
-        fprintf(stdout, "%-25s 1 - Non-repudiation\n", "");
-        fprintf(stdout, "%-25s 2 - Key encipherment\n", "");
-        fprintf(stdout, "%-25s 3 - Data encipherment\n", "");   
-        fprintf(stdout, "%-25s 4 - Key agreement\n", "");
-        fprintf(stdout, "%-25s 5 - Cert signing key\n", "");   
-        fprintf(stdout, "%-25s 6 - CRL signing key\n", "");
-        fprintf(stdout, "%-25s Other to finish\n", "");
-        if (Gets_s (buffer, sizeof(buffer))) {
-            value = PORT_Atoi (buffer);
-            if (value < 0 || value > 6)
-                break;
-            if (value == 0) {
-                /* Checking that zero value of variable 'value'
-                 * corresponds to '0' input made by user */
-                char *chPtr = strchr(buffer, '0');
-                if (chPtr == NULL) {
-                    continue;
-                }
+	if (PrintChoicesAndGetAnswer(
+                "\t\t0 - Dcigital Signature\n"
+                "\t\t1 - Non-repudiation\n"
+                "\t\t2 - Key encipherment\n"
+                "\t\t3 - Data encipherment\n"   
+                "\t\t4 - Key agreement\n"
+                "\t\t5 - Cert signing key\n"   
+                "\t\t6 - CRL signing key\n"
+                "\t\tOther to finish\n",
+                buffer, sizeof(buffer)) == SECFailure) {
+            return SECFailure;
+        }
+        value = PORT_Atoi (buffer);
+        if (value < 0 || value > 6)
+            break;
+        if (value == 0) {
+            /* Checking that zero value of variable 'value'
+             * corresponds to '0' input made by user */
+            char *chPtr = strchr(buffer, '0');
+            if (chPtr == NULL) {
+                continue;
             }
-            keyUsage |= (0x80 >> value);
         }
-        else {/* gets() returns NULL on EOF or error */
-            break;
-        }
+        keyUsage |= (0x80 >> value);
     }
 
     bitStringValue.data = &keyUsage;
     bitStringValue.len = 1;
     yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
 
     return (CERT_EncodeAndAddBitStrExtension
             (extHandle, SEC_OID_X509_KEY_USAGE, &bitStringValue,
@@ -304,22 +315,22 @@ CreateOidSequence(void)
     CERTOidSequence *rv = (CERTOidSequence *)NULL;
     PRArenaPool *arena = (PRArenaPool *)NULL;
 
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if( (PRArenaPool *)NULL == arena ) {
         goto loser;
     }
 
-    rv = (CERTOidSequence *)PORT_ArenaZAlloc(arena, sizeof(CERTOidSequence));
+    rv = (CERTOidSequence *)PORT_ArenaZNew(arena, CERTOidSequence);
     if( (CERTOidSequence *)NULL == rv ) {
         goto loser;
     }
 
-    rv->oids = (SECItem **)PORT_ArenaZAlloc(arena, sizeof(SECItem *));
+    rv->oids = (SECItem **)PORT_ArenaZNew(arena, SECItem *);
     if( (SECItem **)NULL == rv->oids ) {
         goto loser;
     }
 
     rv->arena = arena;
     return rv;
 
 loser:
@@ -354,18 +365,17 @@ AddOidToSequence(CERTOidSequence *os, SE
         count++;
     }
 
     /* ArenaZRealloc */
 
     {
         PRUint32 i;
 
-        oids = (SECItem **)PORT_ArenaZAlloc(os->arena,
-                                            sizeof(SECItem *) * (count+2));
+        oids = (SECItem **)PORT_ArenaZNewArray(os->arena, SECItem *, count + 2);
         if( (SECItem **)NULL == oids ) {
             return SECFailure;
         }
     
         for( i = 0; i < count; i++ ) {
             oids[i] = os->oids[i];
         }
 
@@ -387,17 +397,17 @@ SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
   };
 
 
 static SECItem *
 EncodeOidSequence(CERTOidSequence *os)
 {
     SECItem *rv;
 
-    rv = (SECItem *)PORT_ArenaZAlloc(os->arena, sizeof(SECItem));
+    rv = (SECItem *)PORT_ArenaZNew(os->arena, SECItem);
     if( (SECItem *)NULL == rv ) {
         goto loser;
     }
 
     if( !SEC_ASN1EncodeItem(os->arena, rv, os, CERT_OidSeqTemplate) ) {
         goto loser;
     }
 
@@ -418,29 +428,27 @@ AddExtKeyUsage (void *extHandle)
     PRBool yesNoAns;
 
     os = CreateOidSequence();
     if( (CERTOidSequence *)NULL == os ) {
         return SECFailure;
     }
 
     while (1) {
-        fprintf(stdout, "%-25s 0 - Server Auth\n", "");
-        fprintf(stdout, "%-25s 1 - Client Auth\n", "");
-        fprintf(stdout, "%-25s 2 - Code Signing\n", "");
-        fprintf(stdout, "%-25s 3 - Email Protection\n", "");
-        fprintf(stdout, "%-25s 4 - Timestamp\n", "");
-        fprintf(stdout, "%-25s 5 - OCSP Responder\n", "");
-        fprintf(stdout, "%-25s 6 - Step-up\n", "");
-        fprintf(stdout, "%-25s Other to finish\n", "");
-
-        if (Gets_s(buffer, sizeof(buffer)) == NULL) {
-            PORT_SetError(SEC_ERROR_INPUT_LEN);
-            rv = SECFailure;
-            goto loser;
+        if (PrintChoicesAndGetAnswer(
+                "\t\t0 - Server Auth\n"
+                "\t\t1 - Client Auth\n"
+                "\t\t2 - Code Signing\n"
+                "\t\t3 - Email Protection\n"
+                "\t\t4 - Timestamp\n"
+                "\t\t5 - OCSP Responder\n"
+                "\t\t6 - Step-up\n"
+                "\t\tOther to finish\n",
+                buffer, sizeof(buffer)) == SECFailure) {
+            GEN_BREAK(SECFailure);
         }
         value = PORT_Atoi(buffer);
 
         if (value == 0) {
             /* Checking that zero value of variable 'value'
              * corresponds to '0' input made by user */
             char *chPtr = strchr(buffer, '0');
             if (chPtr == NULL) {
@@ -495,27 +503,27 @@ AddNscpCertType (void *extHandle)
 {
     SECItem bitStringValue;
     unsigned char keyUsage = 0x0;
     char buffer[5];
     int value;
     PRBool yesNoAns;
 
     while (1) {
-        fprintf(stdout, "%-25s 0 - SSL Client\n", "");
-        fprintf(stdout, "%-25s 1 - SSL Server\n", "");
-        fprintf(stdout, "%-25s 2 - S/MIME\n", "");
-        fprintf(stdout, "%-25s 3 - Object Signing\n", "");   
-        fprintf(stdout, "%-25s 4 - Reserved for future use\n", "");
-        fprintf(stdout, "%-25s 5 - SSL CA\n", "");   
-        fprintf(stdout, "%-25s 6 - S/MIME CA\n", "");
-        fprintf(stdout, "%-25s 7 - Object Signing CA\n", "");
-        fprintf(stdout, "%-25s Other to finish\n", "");
-        if (Gets_s (buffer, sizeof(buffer)) == NULL) {
-            PORT_SetError(SEC_ERROR_INPUT_LEN);
+        if (PrintChoicesAndGetAnswer(
+                "\t\t0 - SSL Client\n"
+                "\t\t1 - SSL Server\n"
+                "\t\t2 - S/MIME\n"
+                "\t\t3 - Object Signing\n"   
+                "\t\t4 - Reserved for future use\n"
+                "\t\t5 - SSL CA\n"   
+                "\t\t6 - S/MIME CA\n"
+                "\t\t7 - Object Signing CA\n"
+                "\t\tOther to finish\n",
+                buffer, sizeof(buffer)) == SECFailure) {
             return SECFailure;
         }
         value = PORT_Atoi (buffer);
         if (value < 0 || value > 7)
             break;
         if (value == 0) {
             /* Checking that zero value of variable 'value'
              * corresponds to '0' input made by user */
@@ -622,45 +630,42 @@ AddDNSSubjectAlt(PRArenaPool *arena, CER
     return AddSubjectAltNames(arena, existingListp, dnsNames, certDNSName);
 }
 
 
 static SECStatus 
 AddBasicConstraint(void *extHandle)
 {
     CERTBasicConstraints basicConstraint;    
-    SECItem encodedValue;
     SECStatus rv;
     char buffer[10];
     PRBool yesNoAns;
 
-    encodedValue.data = NULL;
-    encodedValue.len = 0;
     do {
         basicConstraint.pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
         basicConstraint.isCA = GetYesNo ("Is this a CA certificate [y/N]?");
 
         buffer[0] = '\0';
-        puts ("Enter the path length constraint, enter to skip "
-              "[<0 for unlimited path]:");
-        Gets_s (buffer, sizeof(buffer));
+        if (PrintChoicesAndGetAnswer("Enter the path length constraint, "
+                                     "enter to skip [<0 for unlimited path]:",
+                                     buffer, sizeof(buffer)) == SECFailure) {
+            GEN_BREAK(SECFailure);
+        }
         if (PORT_Strlen (buffer) > 0)
             basicConstraint.pathLenConstraint = PORT_Atoi (buffer);
 
-        rv = CERT_EncodeBasicConstraintValue (NULL, &basicConstraint,
-                                              &encodedValue);
-        if (rv)
-            return (rv);
-
         yesNoAns = GetYesNo ("Is this a critical extension [y/N]?");
 
-        rv = CERT_AddExtension(extHandle, SEC_OID_X509_BASIC_CONSTRAINTS,
-                               &encodedValue, yesNoAns, PR_TRUE);
+        rv = SECU_EncodeAndAddExtensionValue(NULL, extHandle,
+                                             &basicConstraint, yesNoAns,
+                                             SEC_OID_X509_BASIC_CONSTRAINTS,
+                                             (EXTEN_EXT_VALUE_ENCODER)
+                                             CERT_EncodeBasicConstraintValue);
     } while (0);
-    PORT_Free (encodedValue.data);
+
     return (rv);
 }
 
 static SECStatus 
 AddAuthKeyID (void *extHandle)
 {
     CERTAuthKeyID *authKeyID = NULL;    
     PRArenaPool *arena = NULL;
@@ -672,17 +677,17 @@ AddAuthKeyID (void *extHandle)
         if ( !arena ) {
             SECU_PrintError(progName, "out of memory");
             GEN_BREAK (SECFailure);
         }
 
         if (GetYesNo ("Enter value for the authKeyID extension [y/N]?") == 0)
             break;
 
-        authKeyID = PORT_ArenaZAlloc (arena, sizeof (CERTAuthKeyID));
+        authKeyID = PORT_ArenaZNew(arena, CERTAuthKeyID);
         if (authKeyID == NULL) {
             GEN_BREAK (SECFailure);
         }
 
         rv = GetString (arena, "Enter value for the key identifier fields,"
                         "enter to omit:", &authKeyID->keyID);
         if (rv != SECSuccess)
             break;
@@ -723,29 +728,29 @@ AddCrlDistPoint(void *extHandle)
 
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if ( !arena )
         return (SECFailure);
 
     do {
         current = NULL;
 
-        current = PORT_ArenaZAlloc (arena, sizeof (*current));
+        current = PORT_ArenaZNew(arena, CRLDistributionPoint);
         if (current == NULL) {
             GEN_BREAK (SECFailure);
         }   
 
         /* Get the distributionPointName fields - this field is optional */
-        puts ("Enter the type of the distribution point name:\n");
-        puts ("\t1 - Full Name\n\t2 - Relative Name\n\tAny other "
-              "number to finish\n\t\tChoice: ");
-        if (Gets_s (buffer, sizeof(buffer)) == NULL) {
-            PORT_SetError(SEC_ERROR_INPUT_LEN);
-            GEN_BREAK (SECFailure);
-        }
+        if (PrintChoicesAndGetAnswer(
+                "Enter the type of the distribution point name:\n"
+                "\t1 - Full Name\n\t2 - Relative Name\n\tAny other "
+                "number to finish\n\t\tChoice: ",
+                buffer, sizeof(buffer)) == SECFailure) {
+	    GEN_BREAK (SECFailure);
+	}
         intValue = PORT_Atoi (buffer);
         switch (intValue) {
         case generalName:
             current->distPointType = intValue;
             current->distPoint.fullName = GetGeneralName (arena);
             rv = PORT_GetError();
             break;
 
@@ -769,26 +774,25 @@ AddCrlDistPoint(void *extHandle)
             CERT_DestroyName (name);
             break;
           }
         }
         if (rv != SECSuccess)
             break;
 
         /* Get the reason flags */
-        puts ("\nSelect one of the following for the reason flags\n");
-        puts ("\t0 - unused\n\t1 - keyCompromise\n\t2 - caCompromise\n"
-              "\t3 - affiliationChanged\n");
-        puts ("\t4 - superseded\n\t5 - cessationOfOperation\n"
-              "\t6 - certificateHold\n");
-        puts ("\tAny other number to finish\t\tChoice: ");
-
-        if (Gets_s (buffer, sizeof(buffer)) == NULL) {
-            PORT_SetError(SEC_ERROR_INPUT_LEN);
-            GEN_BREAK (SECFailure);
+        if (PrintChoicesAndGetAnswer(
+                "\nSelect one of the following for the reason flags\n"
+                "\t0 - unused\n\t1 - keyCompromise\n"
+                "\t2 - caCompromise\n\t3 - affiliationChanged\n"
+                "\t4 - superseded\n\t5 - cessationOfOperation\n"
+                "\t6 - certificateHold\n"
+                "\tAny other number to finish\t\tChoice: ",
+                buffer, sizeof(buffer)) == SECFailure) {
+            GEN_BREAK(SECFailure);
         }
         intValue = PORT_Atoi (buffer);
         if (intValue == 0) {
             /* Checking that zero value of variable 'value'
              * corresponds to '0' input made by user */
             char *chPtr = strchr(buffer, '0');
             if (chPtr == NULL) {
                 intValue = -1;
@@ -803,35 +807,35 @@ AddCrlDistPoint(void *extHandle)
             current->reasons.len = 1;
         }
         puts ("Enter value for the CRL Issuer name:\n");
         current->crlIssuer = GetGeneralName (arena);
         if (current->crlIssuer == NULL && (rv = PORT_GetError()) == SECFailure)
             break;
 
         if (crlDistPoints == NULL) {
-            crlDistPoints = PORT_ArenaZAlloc (arena, sizeof (*crlDistPoints));
+            crlDistPoints = PORT_ArenaZNew(arena, CERTCrlDistributionPoints);
             if (crlDistPoints == NULL) {
                 GEN_BREAK (SECFailure);
             }
         }
-    
+
         crlDistPoints->distPoints =
             PORT_ArenaGrow (arena, crlDistPoints->distPoints,
                             sizeof (*crlDistPoints->distPoints) * count,
                             sizeof (*crlDistPoints->distPoints) *(count + 1));
         if (crlDistPoints->distPoints == NULL) {
             GEN_BREAK (SECFailure);
         }
 
         crlDistPoints->distPoints[count] = current;
         ++count;
         if (GetYesNo ("Enter more value for the CRL distribution "
                       "point extension [y/N]") == 0) {
-            /* Add null to the end of the crlDistPoints to mark end of data */
+            /* Add null to the end to mark end of data */
             crlDistPoints->distPoints =
                 PORT_ArenaGrow(arena, crlDistPoints->distPoints,
                                sizeof (*crlDistPoints->distPoints) * count,
                                sizeof (*crlDistPoints->distPoints) *(count + 1));
             crlDistPoints->distPoints[count] = NULL;    
             break;
         }
 
@@ -847,64 +851,733 @@ AddCrlDistPoint(void *extHandle)
                                              (EXTEN_EXT_VALUE_ENCODER)
                                              CERT_EncodeCRLDistributionPoints);
     }
     if (arena)
         PORT_FreeArena (arena, PR_FALSE);
     return (rv);
 }
 
+
+
+static SECStatus 
+AddPolicyConstraints(void *extHandle)
+{
+    CERTCertificatePolicyConstraints *policyConstr;
+    PRArenaPool *arena = NULL;
+    SECStatus rv = SECSuccess;
+    SECItem *item, *dummy;
+    char buffer[512];
+    int value;
+    PRBool yesNoAns;
+    PRBool skipExt = PR_TRUE;
+
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if ( !arena ) {
+        SECU_PrintError(progName, "out of memory");
+        return SECFailure;
+    }
+
+    policyConstr = PORT_ArenaZNew(arena, CERTCertificatePolicyConstraints);
+    if (policyConstr == NULL) {
+        SECU_PrintError(progName, "out of memory");
+        goto loser;
+    }
+
+    if (PrintChoicesAndGetAnswer("Enter explicit policy value or "
+                                 "Enter to omit",
+                                 buffer, sizeof(buffer)) == SECFailure) {
+        goto loser;
+    }
+
+    if (PORT_Strlen(buffer)) {
+        item = &policyConstr->explicitPolicySkipCerts;
+        value = PORT_Atoi(buffer);
+        dummy = SEC_ASN1EncodeInteger(arena, item, value);
+        if (!dummy) {
+            goto loser;
+        }
+        skipExt = PR_FALSE;
+    }
+    
+    if (PrintChoicesAndGetAnswer("Enter inhibit mapping value or "
+                                 "Enter to omit",
+                                 buffer, sizeof(buffer)) == SECFailure) {
+        goto loser;
+    }
+
+    if (PORT_Strlen(buffer)) {
+        item = &policyConstr->inhibitMappingSkipCerts;
+        value = PORT_Atoi(buffer);
+        dummy = SEC_ASN1EncodeInteger(arena, item, value);
+        if (!dummy) {
+            goto loser;
+        }
+        skipExt = PR_FALSE;
+    }
+ 
+    
+    if (!skipExt) {
+
+        yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+        rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, policyConstr,
+                                             yesNoAns, SEC_OID_X509_POLICY_CONSTRAINTS,
+                                             (EXTEN_EXT_VALUE_ENCODER)
+                                             CERT_EncodePolicyConstraintsExtension);
+    }
+    
+loser:
+    if (arena) {
+        PORT_FreeArena (arena, PR_FALSE);
+    }
+    return (rv);
+}
+
+
+static SECStatus 
+AddInhibitAnyPolicy(void *extHandle)
+{
+    CERTCertificateInhibitAny certInhibitAny;
+    PRArenaPool *arena = NULL;
+    SECStatus rv = SECSuccess;
+    SECItem *item, *dummy;
+    char buffer[10];
+    int value;
+    PRBool yesNoAns;
+    
+
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if ( !arena ) {
+        SECU_PrintError(progName, "out of memory");
+        return SECFailure;
+    }
+
+    if (PrintChoicesAndGetAnswer("Enter the number of certs in the path "
+                                 "permited to use anyPolicy.\n"
+                                 "Enter for 0",
+                                 buffer, sizeof(buffer)) == SECFailure) {
+        goto loser;
+    }
+
+    item = &certInhibitAny.inhibitAnySkipCerts;
+    value = PORT_Atoi(buffer);
+    dummy = SEC_ASN1EncodeInteger(arena, item, value);
+    if (!dummy) {
+        goto loser;
+    }
+    
+    yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+    
+    rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, &certInhibitAny,
+                                         yesNoAns,
+                                         SEC_OID_X509_INHIBIT_ANY_POLICY,
+                                         (EXTEN_EXT_VALUE_ENCODER)
+                                         CERT_EncodeInhibitAnyExtension);
+loser:
+    if (arena) {
+        PORT_FreeArena (arena, PR_FALSE);
+    }
+    return (rv);
+}
+
+
+static SECStatus 
+AddPolicyMappings(void *extHandle)
+{
+    CERTPolicyMap **policyMapArr = NULL;
+    CERTPolicyMap *current;
+    PRArenaPool *arena = NULL;
+    SECStatus rv = SECSuccess;
+    int count = 0;
+    char buffer[512];
+    
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if ( !arena ) {
+        SECU_PrintError(progName, "out of memory");
+        return SECFailure;
+    }
+
+    do {
+        if (PrintChoicesAndGetAnswer("Enter an Object Identifier for Issuer "
+                                     "Domain Policy",
+                                     buffer, sizeof(buffer)) == SECFailure) {
+            GEN_BREAK (SECFailure);
+        }
+
+        current = PORT_ArenaZNew(arena, CERTPolicyMap);
+        if (current == NULL) {
+            GEN_BREAK(SECFailure);
+        }
+
+        rv = SEC_StringToOID(arena, &current->issuerDomainPolicy, buffer, 0);
+        if (rv == SECFailure) {
+            GEN_BREAK(SECFailure);
+        }
+
+        if (PrintChoicesAndGetAnswer("Enter an Object Identifier for "
+                                     "Subject Domain Policy",
+                                     buffer, sizeof(buffer)) == SECFailure) {
+            GEN_BREAK (SECFailure);
+        }
+
+        rv = SEC_StringToOID(arena, &current->subjectDomainPolicy, buffer, 0);
+        if (rv == SECFailure) {
+            GEN_BREAK(SECFailure);
+        }
+
+        if (policyMapArr == NULL) {
+            policyMapArr = PORT_ArenaZNew(arena, CERTPolicyMap *);
+            if (policyMapArr == NULL) {
+                GEN_BREAK (SECFailure);
+            }
+        }
+
+        policyMapArr = PORT_ArenaGrow(arena, policyMapArr,
+                                         sizeof (current) * count,
+                                         sizeof (current) *(count + 1));
+        if (policyMapArr == NULL) {
+            GEN_BREAK (SECFailure);
+        }
+    
+        policyMapArr[count] = current;
+        ++count;
+        
+        if (!GetYesNo("Enter more set to Policy Mappings extension [y/N]")) {
+            /* Add null to the end to mark end of data */
+            policyMapArr = PORT_ArenaGrow (arena, policyMapArr,
+                                           sizeof (current) * count,
+                                           sizeof (current) *(count + 1));
+            if (policyMapArr == NULL) {
+                GEN_BREAK (SECFailure);
+            }
+            policyMapArr[count] = NULL;        
+            break;
+        }
+
+    } while (1);
+
+    if (rv == SECSuccess) {
+        CERTCertificatePolicyMappings mappings;
+        PRBool yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+        mappings.arena = arena;
+        mappings.policyMaps = policyMapArr;
+        rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, &mappings,
+                                             yesNoAns, SEC_OID_X509_POLICY_MAPPINGS,
+                                             (EXTEN_EXT_VALUE_ENCODER)
+                                             CERT_EncodePolicyMappingExtension);
+    }
+    if (arena)
+        PORT_FreeArena (arena, PR_FALSE);
+    return (rv);
+}
+
+enum PoliciQualifierEnum {
+    cpsPointer = 1,
+    userNotice = 2,
+};
+
+
+static CERTPolicyQualifier **
+RequestPolicyQualifiers(PRArenaPool *arena, SECItem *policyID)
+{
+    CERTPolicyQualifier **policyQualifArr = NULL;
+    CERTPolicyQualifier *current;
+    SECStatus rv = SECSuccess;
+    int count = 0;
+    char buffer[512];
+    void *mark;
+    SECOidData *oid = NULL;
+    int intValue = 0;
+    int inCount = 0;
+
+    PORT_Assert(arena);
+    mark = PORT_ArenaMark(arena);
+    do {
+        current = PORT_ArenaZNew(arena, CERTPolicyQualifier);
+        if (current == NULL) {
+            GEN_BREAK(SECFailure);
+        }
+
+        /* Get the accessMethod fields */
+        SECU_PrintObjectID(stdout, policyID,
+                           "Choose the type of qualifier for policy" , 0);
+
+        if (PrintChoicesAndGetAnswer(
+                "\t1 - CPS Pointer qualifier\n"
+                "\t2 - User notice qualifier\n"
+                "\tAny other number to finish\n"
+                "\t\tChoice: ", buffer, sizeof(buffer)) == SECFailure) {
+            GEN_BREAK (SECFailure);
+        }
+        intValue = PORT_Atoi(buffer);
+        switch (intValue) {
+        case cpsPointer: {
+            SECItem input;
+            oid = SECOID_FindOIDByTag(SEC_OID_PKIX_CPS_POINTER_QUALIFIER);
+            if (PrintChoicesAndGetAnswer("Enter CPS Pointer uri: ",
+                                         buffer, sizeof(buffer)) == SECFailure) {
+                GEN_BREAK (SECFailure);
+            }
+            input.len = PORT_Strlen(buffer);
+            input.data = (void*)PORT_ArenaStrdup(arena, buffer);
+            if (input.data == NULL ||
+	        SEC_ASN1EncodeItem(arena, &current->qualifierValue, &input,
+                                   SEC_IA5StringTemplate) == NULL) {
+                GEN_BREAK (SECFailure);
+	    }
+            break;
+        }
+        case userNotice: {
+            SECItem input;
+            SECItem **noticeNumArr;
+            CERTUserNotice *notice = PORT_ArenaZNew(arena, CERTUserNotice);
+            if (!notice) {
+                GEN_BREAK(SECFailure);
+            }
+            
+            oid = SECOID_FindOIDByTag(SEC_OID_PKIX_USER_NOTICE_QUALIFIER);
+
+            if (GetYesNo("\t Enter user notice reference? [y/N]")) {
+
+                if (PrintChoicesAndGetAnswer("Enter user organization: ",
+                                             buffer, sizeof(buffer)) == SECFailure) {
+                    GEN_BREAK (SECFailure);
+                }
+
+                notice->noticeReference.organization.type = siAsciiString;
+                notice->noticeReference.organization.len =
+                    PORT_Strlen(buffer);
+                notice->noticeReference.organization.data =
+                    (void*)PORT_ArenaStrdup(arena, buffer);
+
+
+                noticeNumArr = PORT_ArenaZNewArray(arena, SECItem *, 2);
+		if (!noticeNumArr) {
+                    GEN_BREAK (SECFailure);
+		}
+                
+                do {
+                    SECItem *noticeNum;
+                    
+                    noticeNum = PORT_ArenaZNew(arena, SECItem);
+                    
+                    if (noticeNum == NULL ||
+		        PrintChoicesAndGetAnswer("Enter notice number of any key"
+                                         " to continue:", buffer, sizeof(buffer))
+                                         == SECFailure) {
+                        GEN_BREAK (SECFailure);
+                    }
+                    
+                    intValue = PORT_Atoi(buffer);
+                    if (!SEC_ASN1EncodeInteger(arena, noticeNum, intValue)) {
+                        GEN_BREAK (SECFailure);
+		    }
+                    noticeNumArr[inCount++] = noticeNum;
+                    noticeNumArr[inCount] = NULL;
+                    
+                    if (GetYesNo("Enter one more user notice number[y/N]")) {
+                        noticeNumArr = PORT_ArenaGrow(arena, noticeNumArr,
+                                                      sizeof (current) * inCount,
+                                                   sizeof (current) *(inCount + 1));
+                        if (noticeNumArr == NULL) {
+                            GEN_BREAK (SECFailure);
+                        }
+                    } else {
+			break;
+		    }
+                } while (1);
+                if (rv == SECFailure) {
+                    GEN_BREAK(SECFailure);
+                }
+                notice->noticeReference.noticeNumbers = noticeNumArr;
+                rv = CERT_EncodeNoticeReference(arena, &notice->noticeReference,
+                                                &notice->derNoticeReference);
+                if (rv == SECFailure) {
+                    GEN_BREAK(SECFailure);
+                }
+            }
+            if (GetYesNo("\t Enter user notice text? [y/N]")) {
+                /* Getting only 200 bytes - RFC limitation */
+                if (PrintChoicesAndGetAnswer(
+                        "\t", buffer, 200) == SECFailure) {
+                        GEN_BREAK (SECFailure);
+                }
+                notice->displayText.type = siAsciiString;
+                notice->displayText.len = PORT_Strlen(buffer);
+                notice->displayText.data = (void*)PORT_ArenaStrdup(arena, buffer);
+		if (notice->displayText.data == NULL) {
+		    GEN_BREAK(SECFailure);
+		}
+            }
+
+            rv = CERT_EncodeUserNotice(arena, notice, &current->qualifierValue);
+            if (rv == SECFailure) {
+                GEN_BREAK(SECFailure);
+            }
+
+            break;
+        }
+        }
+        if (rv == SECFailure || oid == NULL ||
+            SECITEM_CopyItem(arena, &current->qualifierID, &oid->oid) == SECFailure) {
+            GEN_BREAK (SECFailure);
+        }
+
+        if (!policyQualifArr) {
+            policyQualifArr = PORT_ArenaZNew(arena, CERTPolicyQualifier *);
+        } else {
+	    policyQualifArr = PORT_ArenaGrow (arena, policyQualifArr,
+                                         sizeof (current) * count,
+                                         sizeof (current) *(count + 1));
+	}
+        if (policyQualifArr == NULL) {
+            GEN_BREAK (SECFailure);
+        }
+    
+        policyQualifArr[count] = current;
+        ++count;
+
+        if (!GetYesNo ("Enter more policy qualifiers for the policy [y/N]")) {
+            /* Add null to the end to mark end of data */
+            policyQualifArr = PORT_ArenaGrow(arena, policyQualifArr,
+                                              sizeof (current) * count,
+                                              sizeof (current) *(count + 1));
+            if (policyQualifArr == NULL) {
+                GEN_BREAK (SECFailure);
+            }
+            policyQualifArr[count] = NULL;        
+            break;
+        }
+
+    } while (1);
+
+    if (rv != SECSuccess) {
+        PORT_ArenaRelease (arena, mark);
+        policyQualifArr = NULL;
+    }
+    return (policyQualifArr);
+}
+
+static SECStatus 
+AddCertPolices(void *extHandle)
+{
+    CERTPolicyInfo **certPoliciesArr = NULL;
+    CERTPolicyInfo *current;
+    PRArenaPool *arena = NULL;
+    SECStatus rv = SECSuccess;
+    int count = 0;
+    char buffer[512];
+
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if ( !arena ) {
+        SECU_PrintError(progName, "out of memory");
+        return SECFailure;
+    }
+
+    do {
+        current = PORT_ArenaZNew(arena, CERTPolicyInfo);
+        if (current == NULL) {
+            GEN_BREAK(SECFailure);
+        }
+        
+        if (PrintChoicesAndGetAnswer("Enter policy ID object identifier"
+                                     " or any for AnyPolicy:",
+                                     buffer, sizeof(buffer)) == SECFailure) {
+            GEN_BREAK (SECFailure);
+        }
+        rv = SEC_StringToOID(arena, &current->policyID, buffer, 0);
+        if (rv == SECFailure) {
+            GEN_BREAK(SECFailure);
+        }
+        
+        current->policyQualifiers = 
+            RequestPolicyQualifiers(arena, &current->policyID); 
+
+        if (!certPoliciesArr) {
+            certPoliciesArr = PORT_ArenaZNew(arena, CERTPolicyInfo *);
+        } else {
+	    certPoliciesArr = PORT_ArenaGrow(arena, certPoliciesArr,
+                                         sizeof (current) * count,
+                                         sizeof (current) *(count + 1));
+	}
+        if (certPoliciesArr == NULL) {
+            GEN_BREAK (SECFailure);
+        }
+    
+        certPoliciesArr[count] = current;
+        ++count;
+        
+        if (!GetYesNo ("Enter more policy information to the"
+                    " Cert Policy extension [y/N]")) {
+            /* Add null to the end to mark end of data */
+            certPoliciesArr = PORT_ArenaGrow(arena, certPoliciesArr,
+                                              sizeof (current) * count,
+                                              sizeof (current) *(count + 1));
+            if (certPoliciesArr == NULL) {
+                GEN_BREAK (SECFailure);
+            }
+            certPoliciesArr[count] = NULL;        
+            break;
+        }
+
+    } while (1);
+
+    if (rv == SECSuccess) {
+        CERTCertificatePolicies policies;
+        PRBool yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+        policies.arena = arena;
+        policies.policyInfos = certPoliciesArr;
+        
+        rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, &policies,
+                                             yesNoAns, SEC_OID_X509_CERTIFICATE_POLICIES,
+                                             (EXTEN_EXT_VALUE_ENCODER)
+                                             CERT_EncodeCertPoliciesExtension);
+    }
+    if (arena)
+    PORT_FreeArena(arena, PR_FALSE);
+    return (rv);
+}
+
+enum AuthInfoAccessTypesEnum {
+    caIssuers = 1,
+    ocsp = 2
+};
+
+enum SubjInfoAccessTypesEnum {
+    caRepository = 1,
+    timeStamping = 2
+};
+    
+/* Encode and add an AIA or SIA extension */
+static SECStatus 
+AddInfoAccess(void *extHandle, PRBool addSIAExt, PRBool isCACert)
+{
+    CERTAuthInfoAccess **infoAccArr = NULL;
+    CERTAuthInfoAccess *current;
+    PRArenaPool *arena = NULL;
+    SECStatus rv = SECSuccess;
+    int count = 0;
+    char buffer[512];
+    SECOidData *oid = NULL;
+    int intValue = 0;
+
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if ( !arena ) {
+        SECU_PrintError(progName, "out of memory");
+        return SECFailure;
+    }
+
+    do {
+        current = NULL;
+        current = PORT_ArenaZNew(arena, CERTAuthInfoAccess);
+        if (current == NULL) {
+            GEN_BREAK(SECFailure);
+        }
+
+        /* Get the accessMethod fields */
+        if (addSIAExt) {
+            if (isCACert) {
+                puts("Adding \"CA Repository\" access method type for "
+                    "Subject Information Access extension:\n");
+                intValue = caRepository;
+            } else {
+                puts("Adding \"Time Stamping Services\" access method type for "
+                    "Subject Information Access extension:\n");
+                intValue = timeStamping;
+            }
+        } else {
+            PrintChoicesAndGetAnswer("Enter access method type "
+                "for Authority Information Access extension:\n"
+                "\t1 - CA Issuers\n\t2 - OCSP\n\tAny"
+                "other number to finish\n\tChoice",
+                buffer, sizeof(buffer));
+            intValue = PORT_Atoi(buffer);
+        }
+        if (addSIAExt) {
+            switch (intValue) {
+              case caRepository:
+                  oid = SECOID_FindOIDByTag(SEC_OID_PKIX_CA_REPOSITORY);
+                  break;
+                  
+              case timeStamping:
+                  oid = SECOID_FindOIDByTag(SEC_OID_PKIX_TIMESTAMPING);
+                  break;
+            } 
+        } else {
+            switch (intValue) {
+              case caIssuers:
+                  oid = SECOID_FindOIDByTag(SEC_OID_PKIX_CA_ISSUERS);
+                  break;
+                  
+              case ocsp:
+                  oid = SECOID_FindOIDByTag(SEC_OID_PKIX_OCSP);
+                  break;
+            } 
+        }
+        if (oid == NULL ||
+            SECITEM_CopyItem(arena, &current->method, &oid->oid) == SECFailure) {
+            GEN_BREAK (SECFailure);
+        }
+
+        current->location = GetGeneralName(arena);
+        if (!current->location) {
+            GEN_BREAK(SECFailure);
+        }
+       
+        if (infoAccArr == NULL) {
+            infoAccArr = PORT_ArenaZNew(arena, CERTAuthInfoAccess *);
+        } else {
+	    infoAccArr = PORT_ArenaGrow(arena, infoAccArr,
+                                     sizeof (current) * count,
+                                     sizeof (current) *(count + 1));
+	}
+        if (infoAccArr == NULL) {
+            GEN_BREAK (SECFailure);
+        }
+    
+        infoAccArr[count] = current;
+        ++count;
+        
+        PR_snprintf(buffer, sizeof(buffer), "Enter more location to the %s"
+                    " Information Access extension [y/N]",
+                    (addSIAExt) ? "Subject" : "Authority");
+
+        if (GetYesNo (buffer) == 0) {
+            /* Add null to the end to mark end of data */
+            infoAccArr = PORT_ArenaGrow(arena, infoAccArr,
+                                         sizeof (current) * count,
+                                         sizeof (current) *(count + 1));
+            if (infoAccArr == NULL) {
+                GEN_BREAK (SECFailure);
+            }
+            infoAccArr[count] = NULL;        
+            break;
+        }
+
+    } while (1);
+
+    if (rv == SECSuccess) {
+        int oidIdent = SEC_OID_X509_AUTH_INFO_ACCESS;
+
+        PRBool yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+        
+        if (addSIAExt) {
+            oidIdent = SEC_OID_X509_SUBJECT_INFO_ACCESS;
+        }
+        rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, infoAccArr,
+                                             yesNoAns, oidIdent,
+                                             (EXTEN_EXT_VALUE_ENCODER)
+                                             CERT_EncodeInfoAccessExtension);
+    }
+    if (arena)
+        PORT_FreeArena(arena, PR_FALSE);
+    return (rv);
+}
+
 SECStatus
 AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames,
-              PRBool  keyUsage, 
-              PRBool  extKeyUsage,
-              PRBool  basicConstraint, 
-              PRBool  authKeyID,
-              PRBool  crlDistPoints, 
-              PRBool  nscpCertType)
+              certutilExtnList extList)
 {
     SECStatus rv = SECSuccess;
+    char *errstring = NULL;
+    
     do {
         /* Add key usage extension */
-        if (keyUsage) {
+        if (extList[ext_keyUsage]) {
             rv = AddKeyUsage(extHandle);
-            if (rv)
+            if (rv) {
+		errstring = "KeyUsage";
                 break;
+	    }
         }
 
         /* Add extended key usage extension */
-        if (extKeyUsage) {
+        if (extList[ext_extKeyUsage]) {
             rv = AddExtKeyUsage(extHandle);
-            if (rv)
+            if (rv) {
+		errstring = "ExtendedKeyUsage";
                 break;
+	    }
         }
 
         /* Add basic constraint extension */
-        if (basicConstraint) {
+        if (extList[ext_basicConstraint]) {
             rv = AddBasicConstraint(extHandle);
-            if (rv)
+            if (rv) {
+		errstring = "BasicConstraint";
+                break;
+	    }
+        }
+
+        if (extList[ext_authorityKeyID]) {
+            rv = AddAuthKeyID(extHandle);
+            if (rv) {
+		errstring = "AuthorityKeyID";
                 break;
+	    }
+        }    
+
+        if (extList[ext_CRLDistPts]) {
+            rv = AddCrlDistPoint(extHandle);
+            if (rv) {
+		errstring = "CRLDistPoints";
+                break;
+	    }
+        }
+
+        if (extList[ext_NSCertType]) {
+            rv = AddNscpCertType(extHandle);
+            if (rv) {
+		errstring = "NSCertType";
+                break;
+	    }
         }
 
-        if (authKeyID) {
-            rv = AddAuthKeyID (extHandle);
-            if (rv)
+        if (extList[ext_authInfoAcc] || extList[ext_subjInfoAcc]) {
+            rv = AddInfoAccess(extHandle, extList[ext_authInfoAcc],
+	                       extList[ext_basicConstraint]);
+            if (rv) {
+		errstring = "InformationAccess";
                 break;
-        }    
+	    }
+        }
 
-        if (crlDistPoints) {
-            rv = AddCrlDistPoint (extHandle);
-            if (rv)
+        if (extList[ext_certPolicies]) {
+            rv = AddCertPolices(extHandle);
+            if (rv) {
+		errstring = "Policies";
                 break;
+	    }
         }
 
-        if (nscpCertType) {
-            rv = AddNscpCertType(extHandle);
-            if (rv)
+        if (extList[ext_policyMappings]) {
+            rv = AddPolicyMappings(extHandle);
+            if (rv) {
+		errstring = "PolicyMappings";
                 break;
+	    }
+        }
+
+        if (extList[ext_policyConstr]) {
+            rv = AddPolicyConstraints(extHandle);
+            if (rv) {
+		errstring = "PolicyConstraints";
+                break;
+	    }
+        }
+
+        if (extList[ext_inhibitAnyPolicy]) {
+            rv = AddInhibitAnyPolicy(extHandle);
+            if (rv) {
+		errstring = "InhibitAnyPolicy";
+                break;
+	    }
         }
 
         if (emailAddrs || dnsNames) {
             PRArenaPool *arena;
             CERTGeneralName *namelist = NULL;
             SECItem item = { 0, NULL, 0 };
             
             arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@@ -913,20 +1586,28 @@ AddExtensions(void *extHandle, const cha
                 break;
             }
 
             rv = AddEmailSubjectAlt(arena, &namelist, emailAddrs);
 
             rv |= AddDNSSubjectAlt(arena, &namelist, dnsNames);
 
             if (rv == SECSuccess) {
-                rv = CERT_EncodeAltNameExtension(arena, namelist, &item);
-                if (rv == SECSuccess) {
+		rv = CERT_EncodeAltNameExtension(arena, namelist, &item);
+	        if (rv == SECSuccess) {
                     rv = CERT_AddExtension(extHandle,
-                                           SEC_OID_X509_SUBJECT_ALT_NAME,
-                                           &item, PR_FALSE, PR_TRUE);
-                }
+                                          SEC_OID_X509_SUBJECT_ALT_NAME,
+                                          &item, PR_FALSE, PR_TRUE);
+		}
             }
-            PORT_FreeArena(arena, PR_FALSE);
+	    PORT_FreeArena(arena, PR_FALSE);
+	    if (rv) {
+                errstring = "SubjectAltName";
+                break;
+	    }
         }
     } while (0);
+    
+    if (rv != SECSuccess) {
+        SECU_PrintError(progName, "Problem creating %s extension", errstring);
+    }
     return rv;
 }
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -63,40 +63,27 @@
 
 #include "pk11func.h"
 #include "secasn1.h"
 #include "cert.h"
 #include "cryptohi.h"
 #include "secoid.h"
 #include "certdb.h"
 #include "nss.h"
+#include "certutil.h"
 
 #define MIN_KEY_BITS		512
 /* MAX_KEY_BITS should agree with MAX_RSA_MODULUS in freebl */
 #define MAX_KEY_BITS		8192
 #define DEFAULT_KEY_BITS	1024
 
 #define GEN_BREAK(e) rv=e; break;
 
-
-extern SECKEYPrivateKey *CERTUTIL_GeneratePrivateKey(KeyType keytype,
-						     PK11SlotInfo *slot, 
-                                                     int rsasize,
-						     int publicExponent,
-						     char *noise,
-						     SECKEYPublicKey **pubkeyp,
-						     char *pqgFile,
-                                                     secuPWData *pwdata);
-
 char *progName;
 
-extern SECStatus
-AddExtensions(void *, const char *, const char *, PRBool, PRBool,
-              PRBool, PRBool, PRBool, PRBool);
-
 static CERTCertificateRequest *
 GetCertRequest(PRFileDesc *inFile, PRBool ascii)
 {
     CERTCertificateRequest *certReq = NULL;
     CERTSignedData signedData;
     PRArenaPool *arena = NULL;
     SECItem reqDER;
     SECStatus rv;
@@ -234,22 +221,17 @@ AddCert(PK11SlotInfo *slot, CERTCertDBHa
 
     return rv;
 }
 
 static SECStatus
 CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
         SECOidTag hashAlgTag, CERTName *subject, char *phone, int ascii, 
 	const char *emailAddrs, const char *dnsNames,
-        PRBool	keyUsage, 
-	PRBool  extKeyUsage,
-	PRBool  basicConstraint, 
-	PRBool  authKeyID,
-	PRBool  crlDistPoints, 
-	PRBool  nscpCertType,
+        certutilExtnList extnList,
         PRFileDesc *outFile)
 {
     CERTSubjectPublicKeyInfo *spki;
     CERTCertificateRequest *cr;
     SECItem *encoding;
     SECOidTag signAlgTag;
     SECItem result;
     SECStatus rv;
@@ -277,28 +259,27 @@ CertReq(SECKEYPrivateKey *privk, SECKEYP
 	return SECFailure;
     }
     
     extHandle = CERT_StartCertificateRequestAttributes(cr);
     if (extHandle == NULL) {
         PORT_FreeArena (arena, PR_FALSE);
 	return SECFailure;
     }
-    if (AddExtensions(extHandle, emailAddrs, dnsNames, keyUsage, extKeyUsage,
-                      basicConstraint, authKeyID, crlDistPoints, nscpCertType)
+    if (AddExtensions(extHandle, emailAddrs, dnsNames, extnList)
                   != SECSuccess) {
         PORT_FreeArena (arena, PR_FALSE);
         return SECFailure;
     }
     CERT_FinishExtensions(extHandle);
     CERT_FinishCertificateRequestAttributes(cr);
 
     /* Der encode the request */
     encoding = SEC_ASN1EncodeItem(arena, NULL, cr,
-		  SEC_ASN1_GET(CERT_CertificateRequestTemplate));
+                                  SEC_ASN1_GET(CERT_CertificateRequestTemplate));
     if (encoding == NULL) {
 	SECU_PrintError(progName, "der encoding of request failed");
 	return SECFailure;
     }
 
     /* Sign the request */
     signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag);
     if (signAlgTag == SEC_OID_UNKNOWN) {
@@ -1401,22 +1382,17 @@ CreateCert(
 	SECOidTag hashAlgTag,
 	unsigned int serialNumber, 
 	int     warpmonths,
 	int     validityMonths,
 	const char *emailAddrs,
 	const char *dnsNames,
 	PRBool  ascii,
 	PRBool  selfsign,
-	PRBool	keyUsage, 
-	PRBool  extKeyUsage,
-	PRBool  basicConstraint, 
-	PRBool  authKeyID,
-	PRBool  crlDistPoints, 
-	PRBool  nscpCertType)
+	certutilExtnList extnList)
 {
     void *	extHandle;
     SECItem *	certDER;
     PRArenaPool *arena			= NULL;
     CERTCertificate *subjectCert 	= NULL;
     CERTCertificateRequest *certReq	= NULL;
     SECStatus 	rv 			= SECSuccess;
     SECItem 	reqDER;
@@ -1442,18 +1418,17 @@ CreateCert(
 	}
         
         
 	extHandle = CERT_StartCertExtensions (subjectCert);
 	if (extHandle == NULL) {
 	    GEN_BREAK (SECFailure)
 	}
         
-        rv = AddExtensions(extHandle, emailAddrs, dnsNames, keyUsage, extKeyUsage,
-                          basicConstraint, authKeyID, crlDistPoints, nscpCertType);
+        rv = AddExtensions(extHandle, emailAddrs, dnsNames, extnList);
         if (rv != SECSuccess) {
 	    GEN_BREAK (SECFailure)
 	}
         
         if (certReq->attributes != NULL &&
 	    certReq->attributes[0] != NULL &&
 	    certReq->attributes[0]->attrType.data != NULL &&
 	    certReq->attributes[0]->attrType.len   > 0    &&
@@ -1637,16 +1612,18 @@ static secuCommandFlag certutil_options 
 
 static const secuCommand certutil = {
     NUM_COMMANDS, 
     NUM_OPTIONS, 
     certutil_commands, 
     certutil_options
 };
 
+static certutilExtnList certutil_extns;
+
 static int 
 certutil_main(int argc, char **argv, PRBool initialize)
 {
     CERTCertDBHandle *certHandle;
     PK11SlotInfo *slot = NULL;
     CERTName *  subject         = 0;
     PRFileDesc *inFile          = PR_STDIN;
     PRFileDesc *outFile         = NULL;
@@ -2191,59 +2168,70 @@ certutil_main(int argc, char **argv, PRB
 
 	/*  If all that was needed was keygen, exit.  */
 	if (certutil.commands[cmd_GenKeyPair].activated) {
 	    rv = SECSuccess;
 	    goto shutdown;
 	}
     }
 
+    /* If we need a list of extensions convert the flags into list format */
+    if (certutil.commands[cmd_CertReq].activated ||
+        certutil.commands[cmd_CreateAndAddCert].activated ||
+        certutil.commands[cmd_CreateNewCert].activated) {
+        certutil_extns[ext_keyUsage] =
+				certutil.options[opt_AddKeyUsageExt].activated;
+        certutil_extns[ext_basicConstraint] =
+				certutil.options[opt_AddBasicConstraintExt].activated;
+        certutil_extns[ext_authorityKeyID] =
+				certutil.options[opt_AddAuthorityKeyIDExt].activated;
+        certutil_extns[ext_CRLDistPts] =
+				certutil.options[opt_AddCRLDistPtsExt].activated;
+        certutil_extns[ext_NSCertType] =
+				certutil.options[opt_AddNSCertTypeExt].activated;
+        certutil_extns[ext_extKeyUsage] =
+				certutil.options[opt_AddExtKeyUsageExt].activated;
+	/* We can't generate the rest of the extensions yet. When long form
+	 * options are available this code block will be extended
+	 */
+    }
     /*
      *  Certificate request
      */
 
     /*  Make a cert request (-R).  */
     if (certutil.commands[cmd_CertReq].activated) {
 	rv = CertReq(privkey, pubkey, keytype, hashAlgTag, subject,
 	             certutil.options[opt_PhoneNumber].arg,
 	             certutil.options[opt_ASCIIForIO].activated,
 		     certutil.options[opt_ExtendedEmailAddrs].arg,
 		     certutil.options[opt_ExtendedDNSNames].arg,
-                     certutil.options[opt_AddKeyUsageExt].activated,
-                     certutil.options[opt_AddExtKeyUsageExt].activated,
-                     certutil.options[opt_AddBasicConstraintExt].activated,
-                     certutil.options[opt_AddAuthorityKeyIDExt].activated,
-                     certutil.options[opt_AddCRLDistPtsExt].activated,
-                     certutil.options[opt_AddNSCertTypeExt].activated,
+                     certutil_extns,
                      outFile ? outFile : PR_STDOUT);
 	if (rv) 
 	    goto shutdown;
 	privkey->wincx = &pwdata;
     }
 
     /*
      *  Certificate creation
      */
 
     /*  If making and adding a cert, create a cert request file first without
      *  any extensions, then load it with the command line extensions
      *  and output the cert to another file.
      */
     if (certutil.commands[cmd_CreateAndAddCert].activated) {
+	static certutilExtnList nullextnlist = {PR_FALSE};
 	rv = CertReq(privkey, pubkey, keytype, hashAlgTag, subject,
 	             certutil.options[opt_PhoneNumber].arg,
 	             certutil.options[opt_ASCIIForIO].activated,
 		     NULL,
 		     NULL,
-                     PR_FALSE,
-                     PR_FALSE,
-                     PR_FALSE,
-                     PR_FALSE,
-                     PR_FALSE,
-                     PR_FALSE,
+                     nullextnlist,
                      outFile ? outFile : PR_STDOUT);
 	if (rv) 
 	    goto shutdown;
 	privkey->wincx = &pwdata;
 	PR_Close(outFile);
 	inFile  = PR_Open(certreqfile, PR_RDONLY, 0);
 	if (!inFile) {
 	    PR_fprintf(PR_STDERR, "Failed to open file \"%s\" (%ld, %ld).\n",
@@ -2266,22 +2254,17 @@ certutil_main(int argc, char **argv, PRB
 	rv = CreateCert(certHandle, 
 	                certutil.options[opt_IssuerName].arg,
 	                inFile, outFile, privkey, &pwdata, hashAlgTag,
 	                serialNumber, warpmonths, validityMonths,
 		        certutil.options[opt_ExtendedEmailAddrs].arg,
 		        certutil.options[opt_ExtendedDNSNames].arg,
 	                certutil.options[opt_ASCIIForIO].activated,
 	                certutil.options[opt_SelfSign].activated,
-	                certutil.options[opt_AddKeyUsageExt].activated,
-	                certutil.options[opt_AddExtKeyUsageExt].activated,
-	                certutil.options[opt_AddBasicConstraintExt].activated,
-	                certutil.options[opt_AddAuthorityKeyIDExt].activated,
-	                certutil.options[opt_AddCRLDistPtsExt].activated,
-	                certutil.options[opt_AddNSCertTypeExt].activated);
+	                certutil_extns);
 	if (rv) 
 	    goto shutdown;
     }
 
     /* 
      * Adding a cert to the database (or slot)
      */
  
--- a/security/nss/lib/certdb/cert.h
+++ b/security/nss/lib/certdb/cert.h
@@ -1553,11 +1553,49 @@ CERT_FindNameConstraintsExten(PRArenaPoo
 			      CERTNameConstraints **constraints);
 
 /*
  * Initialize a new GERTGeneralName fields (link)
  */
 extern CERTGeneralName *
 CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type);
 
+/*
+ * PKIX extension encoding routines
+ */
+extern SECStatus
+CERT_EncodePolicyConstraintsExtension(PRArenaPool *arena,
+                                      CERTCertificatePolicyConstraints *constr,
+                                      SECItem *dest);
+extern SECStatus
+CERT_EncodeInhibitAnyExtension(PRArenaPool *arena,
+                               CERTCertificateInhibitAny *inhibitAny,
+                               SECItem *dest);
+extern SECStatus
+CERT_EncodePolicyMappingExtension(PRArenaPool *arena,
+                                  CERTCertificatePolicyMappings *maps,
+                                  SECItem *dest);
+
+extern SECStatus CERT_EncodeInfoAccessExtension(PRArenaPool *arena,
+                                                    CERTAuthInfoAccess **info,
+                                                    SECItem *dest);
+extern SECStatus
+CERT_EncodeUserNotice(PRArenaPool *arena,
+                      CERTUserNotice *notice,
+                      SECItem *dest);
+
+extern SECStatus
+CERT_EncodeDisplayText(PRArenaPool *arena,
+                       SECItem *text,
+                       SECItem *dest);
+
+extern SECStatus
+CERT_EncodeCertPoliciesExtension(PRArenaPool *arena,
+                                 CERTPolicyInfo **info,
+                                 SECItem *dest);
+extern SECStatus
+CERT_EncodeNoticeReference(PRArenaPool *arena,
+                           CERTNoticeReference *reference,
+                           SECItem *dest);
+
 SEC_END_PROTOS
 
 #endif /* _CERT_H_ */
--- a/security/nss/lib/certdb/polcyxtn.c
+++ b/security/nss/lib/certdb/polcyxtn.c
@@ -44,36 +44,45 @@
 #include "secport.h"
 #include "secder.h"
 #include "cert.h"
 #include "secoid.h"
 #include "secasn1.h"
 #include "secerr.h"
 #include "nspr.h"
 
+const SEC_ASN1Template CERT_DisplayTextTypeTemplate[] = {
+    { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) },
+    { SEC_ASN1_IA5_STRING, 0, 0, siAsciiString},
+    { SEC_ASN1_VISIBLE_STRING , 0, 0, siVisibleString},
+    { SEC_ASN1_BMP_STRING  , 0, 0, siBMPString },
+    { SEC_ASN1_UTF8_STRING , 0, 0, siUTF8String },
+    { 0 }
+};
+
 const SEC_ASN1Template CERT_NoticeReferenceTemplate[] = {
     { SEC_ASN1_SEQUENCE,
 	  0, NULL, sizeof(CERTNoticeReference) },
-/* NOTE: this should be a choice */
-    { SEC_ASN1_IA5_STRING,
-	  offsetof(CERTNoticeReference, organization) },
+    { SEC_ASN1_INLINE,
+	  offsetof(CERTNoticeReference, organization),
+           CERT_DisplayTextTypeTemplate, 0 },
     { SEC_ASN1_SEQUENCE_OF,
-	  offsetof(CERTNoticeReference, noticeNumbers),
-	  SEC_IntegerTemplate }, 
+           offsetof(CERTNoticeReference, noticeNumbers),
+           SEC_IntegerTemplate }, 
     { 0 }
 };
 
-/* this template can not be encoded because of the option inline */
 const SEC_ASN1Template CERT_UserNoticeTemplate[] = {
     { SEC_ASN1_SEQUENCE,
 	  0, NULL, sizeof(CERTUserNotice) },
-    { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED,
-	  offsetof(CERTUserNotice, derNoticeReference) }, 
+    { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
+	  offsetof(CERTUserNotice, displayText),
+           CERT_DisplayTextTypeTemplate, 0 }, 
     { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
-	  offsetof(CERTUserNotice, displayText) }, 
+	  offsetof(CERTUserNotice, derNoticeReference) },
     { 0 }
 };
 
 const SEC_ASN1Template CERT_PolicyQualifierTemplate[] = {
     { SEC_ASN1_SEQUENCE,
 	  0, NULL, sizeof(CERTPolicyQualifier) },
     { SEC_ASN1_OBJECT_ID,
 	  offsetof(CERTPolicyQualifier, qualifierID) },
@@ -424,40 +433,22 @@ CERT_DecodeUserNotice(SECItem *noticeIte
     rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate, 
 			    &newNoticeItem);
 
     if ( rv != SECSuccess ) {
 	goto loser;
     }
 
     if (userNotice->derNoticeReference.data != NULL) {
-	/* sigh, the asn1 parser stripped the sequence encoding, re add it
-	 * before we decode.
-	 */
-	SECItem tmpbuf;
-	int	newBytes;
 
-	newBytes = SEC_ASN1LengthLength(userNotice->derNoticeReference.len)+1;
-	tmpbuf.len = newBytes + userNotice->derNoticeReference.len;
-	tmpbuf.data = PORT_ArenaZAlloc(arena, tmpbuf.len);
-	if (tmpbuf.data == NULL) {
-	    goto loser;
-	}
-	tmpbuf.data[0] = SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED;
-	SEC_ASN1EncodeLength(&tmpbuf.data[1],userNotice->derNoticeReference.len);
-	PORT_Memcpy(&tmpbuf.data[newBytes],userNotice->derNoticeReference.data,
-				userNotice->derNoticeReference.len);
-
-	/* OK, no decode it */
-    	rv = SEC_QuickDERDecodeItem(arena, &userNotice->noticeReference, 
-	    CERT_NoticeReferenceTemplate, &tmpbuf);
-
-	PORT_Free(tmpbuf.data); tmpbuf.data = NULL;
-    	if ( rv != SECSuccess ) {
-	    goto loser;
+        rv = SEC_QuickDERDecodeItem(arena, &userNotice->noticeReference,
+                                    CERT_NoticeReferenceTemplate,
+                                    &userNotice->derNoticeReference);
+        if (rv == SECFailure) {
+            goto loser;
     	}
     }
 
     return(userNotice);
     
 loser:
     if ( arena != NULL ) {
 	PORT_FreeArena(arena, PR_FALSE);
@@ -739,8 +730,127 @@ done:
     if ( oidSeq != NULL ) {
 	CERT_DestroyOidSequence(oidSeq);
     }
     if (extItem.data != NULL) {
 	PORT_Free(extItem.data);
     }
     return(ret);
 }
+
+
+SECStatus
+CERT_EncodePolicyConstraintsExtension(PRArenaPool *arena,
+                                      CERTCertificatePolicyConstraints *constr,
+                                      SECItem *dest)
+{
+    SECStatus rv = SECSuccess;
+
+    PORT_Assert(constr != NULL && dest != NULL);
+    if (constr == NULL || dest == NULL) {
+	return SECFailure;
+    }
+
+    if (SEC_ASN1EncodeItem (arena, dest, constr,
+                            CERT_PolicyConstraintsTemplate) == NULL) {
+	rv = SECFailure;
+    }
+    return(rv);
+}
+
+SECStatus
+CERT_EncodePolicyMappingExtension(PRArenaPool *arena,
+                                  CERTCertificatePolicyMappings *mapping,
+                                  SECItem *dest)
+{
+    SECStatus rv = SECSuccess;
+
+    PORT_Assert(mapping != NULL && dest != NULL);
+    if (mapping == NULL || dest == NULL) {
+	return SECFailure;
+    }
+
+    if (SEC_ASN1EncodeItem (arena, dest, mapping,
+                            CERT_PolicyMappingsTemplate) == NULL) {
+	rv = SECFailure;
+    }
+    return(rv);
+}
+
+
+
+SECStatus
+CERT_EncodeCertPoliciesExtension(PRArenaPool *arena,
+                                 CERTPolicyInfo **info,
+                                 SECItem *dest)
+{
+    SECStatus rv = SECSuccess;
+
+    PORT_Assert(info != NULL && dest != NULL);
+    if (info == NULL || dest == NULL) {
+	return SECFailure;
+    }
+
+    if (SEC_ASN1EncodeItem (arena, dest, info,
+                            CERT_CertificatePoliciesTemplate) == NULL) {
+	rv = SECFailure;
+    }
+    return(rv);
+}
+
+SECStatus
+CERT_EncodeUserNotice(PRArenaPool *arena,
+                      CERTUserNotice *notice,
+                      SECItem *dest)
+{
+    SECStatus rv = SECSuccess;
+
+    PORT_Assert(notice != NULL && dest != NULL);
+    if (notice == NULL || dest == NULL) {
+	return SECFailure;
+    }
+
+    if (SEC_ASN1EncodeItem(arena, dest,
+                           notice, CERT_UserNoticeTemplate) == NULL) {
+	rv = SECFailure;
+    }
+
+    return(rv);
+}
+
+SECStatus
+CERT_EncodeNoticeReference(PRArenaPool *arena,
+                           CERTNoticeReference *reference,
+                           SECItem *dest)
+{
+    SECStatus rv = SECSuccess;
+    
+    PORT_Assert(reference != NULL && dest != NULL);
+    if (reference == NULL || dest == NULL) {
+	return SECFailure;
+    }
+
+    if (SEC_ASN1EncodeItem (arena, dest, reference,
+                            CERT_NoticeReferenceTemplate) == NULL) {
+	rv = SECFailure;
+    }
+
+    return(rv);
+}
+
+SECStatus
+CERT_EncodeInhibitAnyExtension(PRArenaPool *arena,
+                               CERTCertificateInhibitAny *certInhibitAny,
+                               SECItem *dest)
+{
+    SECStatus rv = SECSuccess;
+
+    PORT_Assert(certInhibitAny != NULL && dest != NULL);
+    if (certInhibitAny == NULL || dest == NULL) {
+	return SECFailure;
+    }
+
+    if (SEC_ASN1EncodeItem (arena, dest, certInhibitAny,
+                            CERT_InhibitAnyTemplate) == NULL) {
+	rv = SECFailure;
+    }
+    return(rv);
+}
--- a/security/nss/lib/certdb/xconst.c
+++ b/security/nss/lib/certdb/xconst.c
@@ -288,17 +288,17 @@ CERT_DecodeAuthInfoAccessExtension(PRAre
 	info[i]->location = CERT_DecodeGeneralName(reqArena,
 						   &(info[i]->derLocation),
 						   NULL);
     }
     return info;
 }
 
 SECStatus
-cert_EncodeAuthInfoAccessExtension(PRArenaPool *arena,
+CERT_EncodeInfoAccessExtension(PRArenaPool *arena,
 				   CERTAuthInfoAccess **info,
 				   SECItem *dest)
 {
     SECItem *dummy;
     int i;
 
     PORT_Assert(info != NULL);
     PORT_Assert(dest != NULL);
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -897,16 +897,23 @@ DER_TimeChoiceDayToAscii;
 DER_TimeToGeneralizedTime;
 DER_TimeToGeneralizedTimeArena;
 ;+    local:
 ;+       *;
 ;+};
 ;+NSS_3.12 { 	# NSS 3.12 release
 ;+    global:
 CERT_CheckNameSpace;
+CERT_EncodeCertPoliciesExtension;
+CERT_EncodeInfoAccessExtension;
+CERT_EncodeInhibitAnyExtension;
+CERT_EncodeNoticeReference;
+CERT_EncodePolicyConstraintsExtension;
+CERT_EncodePolicyMappingExtension;
+CERT_EncodeUserNotice;
 CERT_FindCRLEntryReasonExten;
 CERT_FindCRLNumberExten;
 CERT_FindNameConstraintsExten;
 PK11_GetAllSlotsForCert;
 PK11_GenerateKeyPairWithOpFlags;
 SEC_GetRegisteredHttpClient;
 SEC_StringToOID;
 SECKEY_ECParamsToKeySize;
--- a/security/nss/lib/ssl/derive.c
+++ b/security/nss/lib/ssl/derive.c
@@ -39,17 +39,16 @@
 /* $Id$ */
 
 #include "ssl.h" 	/* prereq to sslimpl.h */
 #include "certt.h"	/* prereq to sslimpl.h */
 #include "keythi.h"	/* prereq to sslimpl.h */
 #include "sslimpl.h"
 #include "blapi.h"
 
-#include "secutil.h"
 #include "pk11func.h"
 #include "secasn1.h"
 #include "cert.h"
 #include "secmodt.h"
 
 #include "sslproto.h"
 #include "sslerr.h"
 
--- a/security/nss/lib/util/seccomon.h
+++ b/security/nss/lib/util/seccomon.h
@@ -68,17 +68,20 @@ typedef enum {
     siEncodedCertBuffer = 4,
     siDERNameBuffer = 5,
     siEncodedNameBuffer = 6,
     siAsciiNameString = 7,
     siAsciiString = 8,
     siDEROID = 9,
     siUnsignedInteger = 10,
     siUTCTime = 11,
-    siGeneralizedTime = 12
+    siGeneralizedTime = 12,
+    siVisibleString = 13,
+    siUTF8String = 14,
+    siBMPString = 15
 } SECItemType;
 
 typedef struct SECItemStr SECItem;
 
 struct SECItemStr {
     SECItemType type;
     unsigned char *data;
     unsigned int len;
--- a/security/nss/lib/util/secoid.c
+++ b/security/nss/lib/util/secoid.c
@@ -353,16 +353,18 @@ CONST_OID x509AuthKeyID[]             		
 CONST_OID x509PolicyConstraints[]     		= { ID_CE_OID, 36 };
 CONST_OID x509ExtKeyUsage[]           		= { ID_CE_OID, 37 };
 CONST_OID x509FreshestCRL[]           		= { ID_CE_OID, 46 };
 CONST_OID x509InhibitAnyPolicy[]           	= { ID_CE_OID, 54 };
 
 CONST_OID x509AuthInfoAccess[]        		= { PKIX_CERT_EXTENSIONS,  1 };
 CONST_OID x509SubjectInfoAccess[]               = { PKIX_CERT_EXTENSIONS, 11 };
 
+CONST_OID x509SIATimeStamping[]                 = {PKIX_ACCESS_DESCRIPTION, 0x03};
+CONST_OID x509SIACaRepository[]                 = {PKIX_ACCESS_DESCRIPTION, 0x05};
 
 /* pkcs 12 additions */
 CONST_OID pkcs12[]                           = { PKCS12 };
 CONST_OID pkcs12ModeIDs[]                    = { PKCS12_MODE_IDS };
 CONST_OID pkcs12ESPVKIDs[]                   = { PKCS12_ESPVK_IDS };
 CONST_OID pkcs12BagIDs[]                     = { PKCS12_BAG_IDS };
 CONST_OID pkcs12CertBagIDs[]                 = { PKCS12_CERT_BAG_IDS };
 CONST_OID pkcs12OIDs[]                       = { PKCS12_OIDS };
@@ -1555,16 +1557,24 @@ const static SECOidData oids[] = {
 	CKM_SHA224_HMAC, INVALID_CERT_EXTENSION ),
     OD( hmac_sha256, SEC_OID_HMAC_SHA256, "HMAC SHA-256", 
 	CKM_SHA256_HMAC, INVALID_CERT_EXTENSION ),
     OD( hmac_sha384, SEC_OID_HMAC_SHA384, "HMAC SHA-384", 
 	CKM_SHA384_HMAC, INVALID_CERT_EXTENSION ),
     OD( hmac_sha512, SEC_OID_HMAC_SHA512, "HMAC SHA-512", 
 	CKM_SHA512_HMAC, INVALID_CERT_EXTENSION ),
 
+    /* SIA extension OIDs */
+    OD( x509SIATimeStamping,          SEC_OID_PKIX_TIMESTAMPING,
+        "SIA Time Stamping",          CKM_INVALID_MECHANISM,
+	INVALID_CERT_EXTENSION ),
+    OD( x509SIACaRepository,          SEC_OID_PKIX_CA_REPOSITORY,
+        "SIA CA Repository",          CKM_INVALID_MECHANISM,
+	INVALID_CERT_EXTENSION ),
+
 };
 
 /*
  * now the dynamic table. The dynamic table gets build at init time.
  * and conceivably gets modified if the user loads new crypto modules.
  * All this static data, and the allocated data to which it points,
  * is protected by a global reader/writer lock.  
  * The c language guarantees that global and static data that is not 
--- a/security/nss/lib/util/secoidt.h
+++ b/security/nss/lib/util/secoidt.h
@@ -433,16 +433,19 @@ typedef enum {
     SEC_OID_PKCS5_PBES2                     = 292,
     SEC_OID_PKCS5_PBMAC1                    = 293,
     SEC_OID_HMAC_SHA1                       = 294,
     SEC_OID_HMAC_SHA224                     = 295,
     SEC_OID_HMAC_SHA256                     = 296,
     SEC_OID_HMAC_SHA384                     = 297,
     SEC_OID_HMAC_SHA512                     = 298,
 
+    SEC_OID_PKIX_TIMESTAMPING               = 299,
+    SEC_OID_PKIX_CA_REPOSITORY              = 300,
+
     SEC_OID_TOTAL
 } SECOidTag;
 
 #define SEC_OID_SECG_EC_SECP192R1 SEC_OID_ANSIX962_EC_PRIME192V1
 #define SEC_OID_SECG_EC_SECP256R1 SEC_OID_ANSIX962_EC_PRIME256V1
 #define SEC_OID_PKCS12_KEY_USAGE  SEC_OID_X509_KEY_USAGE
 
 /* fake OID for DSS sign/verify */