mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
r=nelson Bug=263779
This commit is contained in:
parent
22e4705847
commit
5431bc6445
@ -398,10 +398,21 @@ getSignatureOidTag(KeyType keyType, SECOidTag hashAlgTag)
|
||||
return sigTag;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
AddExtensions(void *, const char *, const char *, PRBool, PRBool, PRBool, PRBool,
|
||||
PRBool, PRBool);
|
||||
|
||||
static SECStatus
|
||||
CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
|
||||
SECOidTag hashAlgTag, CERTName *subject, char *phone, int ascii,
|
||||
const char *emailAddrs, const char *dnsNames, PRFileDesc *outFile)
|
||||
const char *emailAddrs, const char *dnsNames,
|
||||
PRBool keyUsage,
|
||||
PRBool extKeyUsage,
|
||||
PRBool basicConstraint,
|
||||
PRBool authKeyID,
|
||||
PRBool crlDistPoints,
|
||||
PRBool nscpCertType,
|
||||
PRFileDesc *outFile)
|
||||
{
|
||||
CERTSubjectPublicKeyInfo *spki;
|
||||
CERTCertificateRequest *cr;
|
||||
@ -411,6 +422,7 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
|
||||
SECStatus rv;
|
||||
PRArenaPool *arena;
|
||||
PRInt32 numBytes;
|
||||
void *extHandle;
|
||||
|
||||
/* Create info about public key */
|
||||
spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
|
||||
@ -418,9 +430,9 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
|
||||
SECU_PrintError(progName, "unable to create subject public key");
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
/* Generate certificate request */
|
||||
cr = CERT_CreateCertificateRequest(subject, spki, 0);
|
||||
cr = CERT_CreateCertificateRequest(subject, spki, NULL);
|
||||
if (!cr) {
|
||||
SECU_PrintError(progName, "unable to make certificate request");
|
||||
return SECFailure;
|
||||
@ -432,6 +444,20 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
extHandle = CERT_StartCertificateRequestAttributes(cr);
|
||||
if (extHandle == NULL) {
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return SECFailure;
|
||||
}
|
||||
if (AddExtensions(extHandle, emailAddrs, PR_FALSE, PR_FALSE, PR_FALSE,
|
||||
PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE)
|
||||
!= 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));
|
||||
@ -2080,6 +2106,71 @@ AddCrlDistPoint(void *extHandle)
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames,
|
||||
PRBool keyUsage,
|
||||
PRBool extKeyUsage,
|
||||
PRBool basicConstraint,
|
||||
PRBool authKeyID,
|
||||
PRBool crlDistPoints,
|
||||
PRBool nscpCertType)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
do {
|
||||
/* Add key usage extension */
|
||||
if (keyUsage) {
|
||||
rv = AddKeyUsage(extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add extended key usage extension */
|
||||
if (extKeyUsage) {
|
||||
rv = AddExtKeyUsage(extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add basic constraint extension */
|
||||
if (basicConstraint) {
|
||||
rv = AddBasicConstraint(extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (authKeyID) {
|
||||
rv = AddAuthKeyID (extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (crlDistPoints) {
|
||||
rv = AddCrlDistPoint (extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (nscpCertType) {
|
||||
rv = AddNscpCertType(extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (emailAddrs != NULL) {
|
||||
rv = AddEmailSubjectAlt(extHandle,emailAddrs);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dnsNames != NULL) {
|
||||
rv = AddDNSSubjectAlt(extHandle,dnsNames);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
CreateCert(
|
||||
CERTCertDBHandle *handle,
|
||||
@ -2110,6 +2201,7 @@ CreateCert(
|
||||
CERTCertificateRequest *certReq = NULL;
|
||||
SECStatus rv = SECSuccess;
|
||||
SECItem reqDER;
|
||||
CERTCertExtension **CRexts;
|
||||
|
||||
reqDER.data = NULL;
|
||||
do {
|
||||
@ -2129,63 +2221,29 @@ CreateCert(
|
||||
if (subjectCert == NULL) {
|
||||
GEN_BREAK (SECFailure)
|
||||
}
|
||||
|
||||
|
||||
|
||||
extHandle = CERT_StartCertExtensions (subjectCert);
|
||||
if (extHandle == NULL) {
|
||||
GEN_BREAK (SECFailure)
|
||||
}
|
||||
|
||||
/* Add key usage extension */
|
||||
if (keyUsage) {
|
||||
rv = AddKeyUsage(extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add extended key usage extension */
|
||||
if (extKeyUsage) {
|
||||
rv = AddExtKeyUsage(extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add basic constraint extension */
|
||||
if (basicConstraint) {
|
||||
rv = AddBasicConstraint(extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (authKeyID) {
|
||||
rv = AddAuthKeyID (extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (crlDistPoints) {
|
||||
rv = AddCrlDistPoint (extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (nscpCertType) {
|
||||
rv = AddNscpCertType(extHandle);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (emailAddrs != NULL) {
|
||||
rv = AddEmailSubjectAlt(extHandle,emailAddrs);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dnsNames != NULL) {
|
||||
rv = AddDNSSubjectAlt(extHandle,dnsNames);
|
||||
if (rv)
|
||||
break;
|
||||
|
||||
rv = AddExtensions(extHandle, emailAddrs, dnsNames, keyUsage, extKeyUsage,
|
||||
basicConstraint, authKeyID, crlDistPoints, nscpCertType);
|
||||
if (rv != SECSuccess) {
|
||||
GEN_BREAK (SECFailure)
|
||||
}
|
||||
|
||||
if (certReq->attributes != NULL &&
|
||||
SECOID_FindOIDTag(&(*certReq->attributes)->attrType)
|
||||
== SEC_OID_PKCS9_EXTENSION_REQUEST) {
|
||||
rv = CERT_GetCertificateRequestExtensions(certReq, &CRexts);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = CERT_MergeExtensions(extHandle, CRexts);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
|
||||
CERT_FinishExtensions(extHandle);
|
||||
|
||||
@ -2877,7 +2935,13 @@ secuCommandFlag certutil_options[] =
|
||||
certutil.options[opt_ASCIIForIO].activated,
|
||||
certutil.options[opt_ExtendedEmailAddrs].arg,
|
||||
certutil.options[opt_ExtendedDNSNames].arg,
|
||||
outFile ? outFile : PR_STDOUT);
|
||||
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,
|
||||
outFile ? outFile : PR_STDOUT);
|
||||
if (rv)
|
||||
goto shutdown;
|
||||
privkey->wincx = &pwdata;
|
||||
|
@ -37,7 +37,7 @@
|
||||
/*
|
||||
* cert.h - public data structures and prototypes for the certificate library
|
||||
*
|
||||
* $Id: cert.h,v 1.52 2005/03/08 07:08:43 julien.pierre.bugs%sun.com Exp $
|
||||
* $Id: cert.h,v 1.53 2005/03/09 23:02:47 neil.williams%sun.com Exp $
|
||||
*/
|
||||
|
||||
#ifndef _CERT_H_
|
||||
@ -250,6 +250,26 @@ CERT_CreateCertificateRequest (CERTName *name, CERTSubjectPublicKeyInfo *spki,
|
||||
*/
|
||||
extern void CERT_DestroyCertificateRequest(CERTCertificateRequest *r);
|
||||
|
||||
/*
|
||||
** Start adding extensions to a certificate request.
|
||||
*/
|
||||
void *
|
||||
CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req);
|
||||
|
||||
/*
|
||||
** Reformat the certifcate extension list into a CertificateRequest
|
||||
** attribute list.
|
||||
*/
|
||||
SECStatus
|
||||
CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req);
|
||||
|
||||
/*
|
||||
** Extract the Extension Requests from a DER CertRequest attribute list.
|
||||
*/
|
||||
SECStatus
|
||||
CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
|
||||
CERTCertExtension ***exts);
|
||||
|
||||
/*
|
||||
** Extract a public key object from a certificate
|
||||
*/
|
||||
@ -823,6 +843,13 @@ CERT_EncodeAltNameExtension(PRArenaPool *arena, CERTGeneralName *value, SECIte
|
||||
*/
|
||||
extern SECStatus CERT_FinishExtensions(void *exthandle);
|
||||
|
||||
/*
|
||||
** Merge an external list of extensions into a cert's extension list, adding one
|
||||
** only when its OID matches none of the cert's existing extensions. Call this
|
||||
** immediately before calling CERT_FinishExtensions().
|
||||
*/
|
||||
SECStatus
|
||||
CERT_MergeExtensions(void *exthandle, CERTCertExtension **exts);
|
||||
|
||||
/* If the extension is found, return its criticality and value.
|
||||
** This allocate storage for the returning extension value.
|
||||
|
@ -375,6 +375,51 @@ loser:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
|
||||
{
|
||||
CERTCertExtension *ext;
|
||||
SECStatus rv = SECSuccess;
|
||||
SECOidTag tag;
|
||||
extNode *node;
|
||||
extRec *handle = exthandle;
|
||||
PRBool critical;
|
||||
|
||||
if (!exthandle || !extensions) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
while ((ext = *extensions++) != NULL) {
|
||||
tag = SECOID_FindOIDTag(&ext->id);
|
||||
for (node=handle->head; node != NULL; node=node->next) {
|
||||
if (tag == 0) {
|
||||
if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (SECOID_FindOIDTag(&node->ext->id) == tag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node == NULL) {
|
||||
PRBool critical = (ext->critical.len != 0 &&
|
||||
ext->critical.data[ext->critical.len - 1] != 0);
|
||||
if (critical && tag == SEC_OID_UNKNOWN) {
|
||||
PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
/* add to list */
|
||||
rv = CERT_AddExtensionByOID (exthandle, &ext->id, &ext->value,
|
||||
critical, PR_TRUE);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the value of the Netscape Certificate Type Extension
|
||||
*/
|
||||
|
@ -35,10 +35,12 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "cert.h"
|
||||
#include "certt.h"
|
||||
#include "secder.h"
|
||||
#include "key.h"
|
||||
#include "secitem.h"
|
||||
#include "secasn1.h"
|
||||
#include "secerr.h"
|
||||
|
||||
const SEC_ASN1Template CERT_AttributeTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
@ -166,8 +168,7 @@ CERT_CreateCertificateRequest(CERTName *subject,
|
||||
|
||||
/* allocate space for attributes */
|
||||
while(attributes[i] != NULL) i++;
|
||||
certreq->attributes = (SECItem**)PORT_ArenaZAlloc(arena,
|
||||
sizeof(SECItem *) * (i + 1));
|
||||
certreq->attributes = PORT_ArenaZNewArray(arena,CERTAttribute*,i+1);
|
||||
if(!certreq->attributes) {
|
||||
goto loser;
|
||||
}
|
||||
@ -231,3 +232,96 @@ CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
setCRExt(void *o, CERTCertExtension **exts)
|
||||
{
|
||||
((CERTCertificateRequest *)o)->attributes = (struct CERTAttributeStr **)exts;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set up to start gathering cert extensions for a cert request.
|
||||
** The list is created as CertExtensions and converted to an
|
||||
** attribute list by CERT_FinishCRAttributes().
|
||||
*/
|
||||
extern void *cert_StartExtensions(void *owner, PRArenaPool *ownerArena,
|
||||
void (*setExts)(void *object, CERTCertExtension **exts));
|
||||
void *
|
||||
CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
|
||||
{
|
||||
return (cert_StartExtensions ((void *)req, req->arena, setCRExt));
|
||||
}
|
||||
|
||||
/*
|
||||
** At entry req->attributes actually contains an list of cert extensions--
|
||||
** req-attributes is overloaded until the list is DER encoded (the first
|
||||
** ...EncodeItem() below).
|
||||
** We turn this into an attribute list by encapsulating it
|
||||
** in a PKCS 10 Attribute structure
|
||||
*/
|
||||
SECStatus
|
||||
CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
|
||||
{ SECItem *extlist;
|
||||
SECOidData *oidrec;
|
||||
CERTAttribute *attribute;
|
||||
|
||||
if (!req || !req->arena) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
if (req->attributes == NULL)
|
||||
return SECSuccess;
|
||||
|
||||
extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes,
|
||||
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate));
|
||||
if (extlist == NULL)
|
||||
return(SECFailure);
|
||||
|
||||
oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
|
||||
if (oidrec == NULL)
|
||||
return SECFailure;
|
||||
|
||||
/* now change the list of cert extensions into a list of attributes
|
||||
*/
|
||||
req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute*, 2);
|
||||
|
||||
attribute = PORT_ArenaZNew(req->arena, CERTAttribute);
|
||||
|
||||
if (req->attributes == NULL || attribute == NULL ||
|
||||
SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return SECFailure;
|
||||
}
|
||||
attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem*, 2);
|
||||
|
||||
if (attribute->attrValue == NULL)
|
||||
return SECFailure;
|
||||
|
||||
attribute->attrValue[0] = extlist;
|
||||
attribute->attrValue[1] = NULL;
|
||||
req->attributes[0] = attribute;
|
||||
req->attributes[1] = NULL;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
|
||||
CERTCertExtension ***exts)
|
||||
{
|
||||
if (req == NULL || exts == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (req->attributes == NULL || *req->attributes == NULL)
|
||||
return SECSuccess;
|
||||
|
||||
if ((*req->attributes)->attrValue == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return(SEC_ASN1DecodeItem(req->arena, exts,
|
||||
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
|
||||
(*req->attributes)->attrValue[0]));
|
||||
}
|
||||
|
@ -820,11 +820,15 @@ CERT_DecodeCRLDistributionPoints;
|
||||
CERT_DecodeNameConstraintsExtension;
|
||||
CERT_DecodePrivKeyUsagePeriodExtension;
|
||||
CERT_DestroyUserNotice;
|
||||
CERT_FinishCertificateRequestAttributes;
|
||||
CERT_GetCertificateNames;
|
||||
CERT_GetCertificateRequestExtensions;
|
||||
CERT_GetNextGeneralName;
|
||||
CERT_GetNextNameConstraint;
|
||||
CERT_GetPrevGeneralName;
|
||||
CERT_GetPrevNameConstraint;
|
||||
CERT_MergeExtensions;
|
||||
CERT_StartCertificateRequestAttributes;
|
||||
CERT_StartCRLEntryExtensions;
|
||||
CERT_StartCRLExtensions;
|
||||
CERT_UncacheCRL;
|
||||
|
Loading…
Reference in New Issue
Block a user