security/nss/lib/crmf/crmfreq.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/crmf/crmfreq.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,670 @@
     1.4 +/* -*- Mode: C; tab-width: 8 -*-*/
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "crmf.h"
    1.10 +#include "crmfi.h"
    1.11 +#include "keyhi.h"
    1.12 +#include "secder.h"
    1.13 +
    1.14 +/*
    1.15 + * Macro that returns PR_TRUE if the pointer is not NULL.
    1.16 + * If the pointer is NULL, then the macro will return PR_FALSE.
    1.17 + */
    1.18 +#define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE
    1.19 +
    1.20 +const unsigned char hexTrue  = 0xff;
    1.21 +const unsigned char hexFalse = 0x00;
    1.22 +
    1.23 +
    1.24 +SECStatus
    1.25 +crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value)
    1.26 +{
    1.27 +    SECItem *dummy;
    1.28 +
    1.29 +    dummy = SEC_ASN1EncodeInteger(poolp, dest, value);
    1.30 +    PORT_Assert (dummy == dest);
    1.31 +    if (dummy == NULL) {
    1.32 +        return SECFailure;
    1.33 +    }
    1.34 +    return SECSuccess;
    1.35 +}
    1.36 +
    1.37 +SECStatus
    1.38 +crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest,
    1.39 +                             unsigned long value) 
    1.40 +{
    1.41 +    SECItem *dummy;
    1.42 +
    1.43 +    dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value);
    1.44 +    PORT_Assert (dummy == dest);
    1.45 +    if (dummy != dest) {
    1.46 +        return SECFailure;
    1.47 +    }
    1.48 +    return SECSuccess;
    1.49 +}
    1.50 +
    1.51 +static SECStatus
    1.52 +crmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src)
    1.53 +{
    1.54 +    return  SECITEM_CopyItem (poolp, dest, src); 
    1.55 +}
    1.56 +
    1.57 +PRBool
    1.58 +CRMF_DoesRequestHaveField (CRMFCertRequest       *inCertReq, 
    1.59 +			   CRMFCertTemplateField  inField)
    1.60 +{
    1.61 +  
    1.62 +    PORT_Assert(inCertReq != NULL);
    1.63 +    if (inCertReq == NULL) {
    1.64 +        return PR_FALSE;
    1.65 +    }
    1.66 +    switch (inField) {
    1.67 +    case crmfVersion:
    1.68 +        return inCertReq->certTemplate.version.data != NULL;
    1.69 +    case crmfSerialNumber:
    1.70 +        return inCertReq->certTemplate.serialNumber.data != NULL;
    1.71 +    case crmfSigningAlg:
    1.72 +        return inCertReq->certTemplate.signingAlg != NULL;
    1.73 +    case crmfIssuer:
    1.74 +        return inCertReq->certTemplate.issuer != NULL;
    1.75 +    case crmfValidity:
    1.76 +        return inCertReq->certTemplate.validity != NULL;
    1.77 +    case crmfSubject:
    1.78 +        return inCertReq->certTemplate.subject != NULL;
    1.79 +    case crmfPublicKey:
    1.80 +        return inCertReq->certTemplate.publicKey != NULL;
    1.81 +    case crmfIssuerUID:
    1.82 +        return inCertReq->certTemplate.issuerUID.data != NULL;
    1.83 +    case crmfSubjectUID:
    1.84 +        return inCertReq->certTemplate.subjectUID.data != NULL;
    1.85 +    case crmfExtension:
    1.86 +        return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0;
    1.87 +    }
    1.88 +    return PR_FALSE;
    1.89 +}
    1.90 +
    1.91 +CRMFCertRequest *
    1.92 +CRMF_CreateCertRequest (PRUint32 inRequestID)
    1.93 +{
    1.94 +    PLArenaPool     *poolp;
    1.95 +    CRMFCertRequest *certReq;
    1.96 +    SECStatus        rv;
    1.97 +    
    1.98 +    poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
    1.99 +    if (poolp == NULL) {
   1.100 +        goto loser;
   1.101 +    }
   1.102 +    
   1.103 +    certReq=PORT_ArenaZNew(poolp,CRMFCertRequest);
   1.104 +    if (certReq == NULL) {
   1.105 +        goto loser;
   1.106 +    }
   1.107 +
   1.108 +    certReq->poolp = poolp;
   1.109 +    certReq->requestID = inRequestID;
   1.110 +    
   1.111 +    rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId), 
   1.112 +                                      inRequestID);
   1.113 +    if (rv != SECSuccess) {
   1.114 +        goto loser;
   1.115 +    }
   1.116 +
   1.117 +    return certReq;
   1.118 + loser:
   1.119 +    if (poolp) {
   1.120 +        PORT_FreeArena(poolp, PR_FALSE);
   1.121 +    }
   1.122 +    return NULL;
   1.123 +}
   1.124 +
   1.125 +SECStatus
   1.126 +CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq)
   1.127 +{
   1.128 +    PORT_Assert(inCertReq != NULL);
   1.129 +    if (inCertReq != NULL) {
   1.130 +        if (inCertReq->certTemplate.extensions) {
   1.131 +	    PORT_Free(inCertReq->certTemplate.extensions);
   1.132 +	}
   1.133 +	if (inCertReq->controls) {
   1.134 +	    /* Right now we don't support EnveloppedData option,
   1.135 +	     * so we won't go through and delete each occurrence of 
   1.136 +	     * an EnveloppedData in the control.
   1.137 +	     */
   1.138 +	    PORT_Free(inCertReq->controls);
   1.139 +	}
   1.140 +	if (inCertReq->poolp) {
   1.141 +	    PORT_FreeArena(inCertReq->poolp, PR_TRUE);
   1.142 +	}
   1.143 +    }
   1.144 +    return SECSuccess;
   1.145 +}
   1.146 +
   1.147 +static SECStatus
   1.148 +crmf_template_add_version(PLArenaPool *poolp, SECItem *dest, long version)
   1.149 +{
   1.150 +    return (crmf_encode_integer(poolp, dest, version));
   1.151 +}
   1.152 +
   1.153 +static SECStatus
   1.154 +crmf_template_add_serialnumber(PLArenaPool *poolp, SECItem *dest, long serial)
   1.155 +{
   1.156 +    return (crmf_encode_integer(poolp, dest, serial));
   1.157 +}
   1.158 +
   1.159 +SECStatus
   1.160 +crmf_template_copy_secalg (PLArenaPool *poolp, SECAlgorithmID **dest,
   1.161 +			   SECAlgorithmID* src)
   1.162 +{
   1.163 +    SECStatus         rv;
   1.164 +    void             *mark = NULL;
   1.165 +    SECAlgorithmID   *mySecAlg;
   1.166 +
   1.167 +    if (!poolp) {
   1.168 +        PORT_SetError(SEC_ERROR_INVALID_ARGS);
   1.169 +        return SECFailure;
   1.170 +    }
   1.171 +
   1.172 +    mark = PORT_ArenaMark(poolp);
   1.173 +    *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID);
   1.174 +    if (mySecAlg == NULL) {
   1.175 +        goto loser;
   1.176 +    }
   1.177 +    rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src);
   1.178 +    if (rv != SECSuccess) {
   1.179 +        goto loser;
   1.180 +    }
   1.181 +    if (mark) {
   1.182 +        PORT_ArenaUnmark(poolp, mark);
   1.183 +    }
   1.184 +    return SECSuccess;
   1.185 +
   1.186 + loser:
   1.187 +    *dest = NULL;
   1.188 +    if (mark) {
   1.189 +        PORT_ArenaRelease(poolp, mark);
   1.190 +    }
   1.191 +    return SECFailure;
   1.192 +}
   1.193 +
   1.194 +SECStatus
   1.195 +crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest,
   1.196 +		    CERTName *src)
   1.197 +{
   1.198 +    CERTName *newName;
   1.199 +    SECStatus rv;
   1.200 +    void     *mark;
   1.201 +
   1.202 +    mark = PORT_ArenaMark(poolp);
   1.203 +    *dest = newName = PORT_ArenaZNew(poolp, CERTName);
   1.204 +    if (newName == NULL) {
   1.205 +        goto loser;
   1.206 +    }
   1.207 +
   1.208 +    rv = CERT_CopyName(poolp, newName, src);
   1.209 +    if (rv != SECSuccess) {
   1.210 +      goto loser;
   1.211 +    }
   1.212 +    PORT_ArenaUnmark(poolp, mark);
   1.213 +    return SECSuccess;
   1.214 + loser:
   1.215 +    PORT_ArenaRelease(poolp, mark);
   1.216 +    *dest = NULL;
   1.217 +    return SECFailure;
   1.218 +}
   1.219 +
   1.220 +static SECStatus
   1.221 +crmf_template_add_issuer (PLArenaPool *poolp, CERTName **dest,
   1.222 +			  CERTName* issuerName)
   1.223 +{
   1.224 +    return crmf_copy_cert_name(poolp, dest, issuerName);
   1.225 +}
   1.226 +
   1.227 +
   1.228 +static SECStatus
   1.229 +crmf_template_add_validity (PLArenaPool *poolp, CRMFOptionalValidity **dest,
   1.230 +			    CRMFValidityCreationInfo *info)
   1.231 +{
   1.232 +    SECStatus             rv;
   1.233 +    void                 *mark; 
   1.234 +    CRMFOptionalValidity *myValidity;
   1.235 +
   1.236 +    /*First off, let's make sure at least one of the two fields is present*/
   1.237 +    if (!info  || (!info->notBefore && !info->notAfter)) {
   1.238 +        return SECFailure;
   1.239 +    }
   1.240 +    mark = PORT_ArenaMark (poolp);
   1.241 +    *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity);
   1.242 +    if (myValidity == NULL) {
   1.243 +        goto loser;
   1.244 +    }
   1.245 +
   1.246 +    if (info->notBefore) {
   1.247 +        rv = DER_EncodeTimeChoice (poolp, &myValidity->notBefore, 
   1.248 +				  *info->notBefore);
   1.249 +	if (rv != SECSuccess) {
   1.250 +	    goto loser;
   1.251 +	}
   1.252 +    }
   1.253 +    if (info->notAfter) {
   1.254 +        rv = DER_EncodeTimeChoice (poolp, &myValidity->notAfter,
   1.255 +				  *info->notAfter);
   1.256 +	if (rv != SECSuccess) {
   1.257 +	    goto loser;
   1.258 +	}
   1.259 +    }
   1.260 +    PORT_ArenaUnmark(poolp, mark);
   1.261 +    return SECSuccess;
   1.262 + loser:
   1.263 +    PORT_ArenaRelease(poolp, mark);
   1.264 +    *dest = NULL;
   1.265 +    return SECFailure;
   1.266 +}
   1.267 +
   1.268 +static SECStatus
   1.269 +crmf_template_add_subject (PLArenaPool *poolp, CERTName **dest,
   1.270 +			   CERTName *subject)
   1.271 +{
   1.272 +    return crmf_copy_cert_name(poolp, dest, subject);
   1.273 +}
   1.274 +
   1.275 +SECStatus
   1.276 +crmf_template_add_public_key(PLArenaPool *poolp,
   1.277 +			     CERTSubjectPublicKeyInfo **dest,
   1.278 +			     CERTSubjectPublicKeyInfo  *pubKey)
   1.279 +{
   1.280 +    CERTSubjectPublicKeyInfo *spki;
   1.281 +    SECStatus rv;
   1.282 +
   1.283 +    *dest = spki = (poolp == NULL) ?
   1.284 +                              PORT_ZNew(CERTSubjectPublicKeyInfo) :
   1.285 +                              PORT_ArenaZNew (poolp, CERTSubjectPublicKeyInfo);
   1.286 +    if (spki == NULL) {
   1.287 +        goto loser;
   1.288 +    }
   1.289 +    rv = SECKEY_CopySubjectPublicKeyInfo (poolp, spki, pubKey);
   1.290 +    if (rv != SECSuccess) {
   1.291 +        goto loser;
   1.292 +    }
   1.293 +    return SECSuccess;
   1.294 + loser:
   1.295 +    if (poolp == NULL && spki != NULL) {
   1.296 +        SECKEY_DestroySubjectPublicKeyInfo(spki);
   1.297 +    }
   1.298 +    *dest = NULL;
   1.299 +    return SECFailure;
   1.300 +}
   1.301 +
   1.302 +static SECStatus
   1.303 +crmf_copy_bitstring (PLArenaPool *poolp, SECItem *dest, const SECItem *src)
   1.304 +{
   1.305 +    SECStatus rv;
   1.306 +    SECItem  byteSrc;
   1.307 +    
   1.308 +    byteSrc = *src;
   1.309 +    byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len);
   1.310 +    rv = crmf_copy_secitem(poolp, dest, &byteSrc);
   1.311 +    dest->len = src->len;
   1.312 +    return rv;
   1.313 +}
   1.314 +
   1.315 +static SECStatus
   1.316 +crmf_template_add_issuer_uid(PLArenaPool *poolp, SECItem *dest,
   1.317 +			     const SECItem *issuerUID)
   1.318 +{
   1.319 +    return crmf_copy_bitstring (poolp, dest, issuerUID);
   1.320 +}
   1.321 +
   1.322 +static SECStatus
   1.323 +crmf_template_add_subject_uid(PLArenaPool *poolp, SECItem *dest,
   1.324 +			      const SECItem *subjectUID)
   1.325 +{
   1.326 +    return crmf_copy_bitstring (poolp, dest, subjectUID);
   1.327 +}
   1.328 +
   1.329 +static void
   1.330 +crmf_zeroize_new_extensions (CRMFCertExtension **extensions,
   1.331 +			     int numToZeroize) 
   1.332 +{
   1.333 +    PORT_Memset((void*)extensions, 0, sizeof(CERTCertExtension*)*numToZeroize);
   1.334 +}
   1.335 +
   1.336 +/*
   1.337 + * The strategy for adding templates will differ from all the other
   1.338 + * attributes in the template.  First, we want to allow the client
   1.339 + * of this API to set extensions more than just once.  So we will
   1.340 + * need the ability grow the array of extensions.  Since arenas don't
   1.341 + * give us the realloc function, we'll use the generic PORT_* functions
   1.342 + * to allocate the array of pointers *ONLY*.  Then we will allocate each
   1.343 + * individual extension from the arena that comes along with the certReq
   1.344 + * structure that owns this template.
   1.345 + */
   1.346 +static SECStatus
   1.347 +crmf_template_add_extensions(PLArenaPool *poolp, CRMFCertTemplate *inTemplate,
   1.348 +			     CRMFCertExtCreationInfo *extensions)
   1.349 +{
   1.350 +    void               *mark;
   1.351 +    int                 newSize, oldSize, i;
   1.352 +    SECStatus           rv;
   1.353 +    CRMFCertExtension **extArray;
   1.354 +    CRMFCertExtension  *newExt, *currExt;
   1.355 +
   1.356 +    mark = PORT_ArenaMark(poolp);
   1.357 +    if (inTemplate->extensions == NULL) {
   1.358 +        newSize = extensions->numExtensions;
   1.359 +        extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1);
   1.360 +    } else {
   1.361 +        newSize = inTemplate->numExtensions + extensions->numExtensions;
   1.362 +        extArray = PORT_Realloc(inTemplate->extensions, 
   1.363 +				sizeof(CRMFCertExtension*)*(newSize+1));
   1.364 +    }
   1.365 +    if (extArray == NULL) {
   1.366 +        goto loser;
   1.367 +    }
   1.368 +    oldSize                   = inTemplate->numExtensions;
   1.369 +    inTemplate->extensions    = extArray;
   1.370 +    inTemplate->numExtensions = newSize;
   1.371 +    for (i=oldSize; i < newSize; i++) {
   1.372 +        newExt = PORT_ArenaZNew(poolp, CRMFCertExtension);
   1.373 +	if (newExt == NULL) {
   1.374 +	    goto loser2;
   1.375 +	}
   1.376 +	currExt = extensions->extensions[i-oldSize];
   1.377 +	rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id));
   1.378 +	if (rv != SECSuccess) {
   1.379 +	    goto loser2;
   1.380 +	}
   1.381 +	rv = crmf_copy_secitem(poolp, &(newExt->critical),
   1.382 +			       &(currExt->critical));
   1.383 +	if (rv != SECSuccess) {
   1.384 +	    goto loser2;
   1.385 +	}
   1.386 +	rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value));
   1.387 +	if (rv != SECSuccess) {
   1.388 +	    goto loser2;
   1.389 +	}
   1.390 +	extArray[i] = newExt;
   1.391 +    }
   1.392 +    extArray[newSize] = NULL;
   1.393 +    PORT_ArenaUnmark(poolp, mark);
   1.394 +    return SECSuccess;
   1.395 + loser2:
   1.396 +    crmf_zeroize_new_extensions (&(inTemplate->extensions[oldSize]),
   1.397 +				 extensions->numExtensions);
   1.398 +    inTemplate->numExtensions = oldSize;
   1.399 + loser:
   1.400 +    PORT_ArenaRelease(poolp, mark);
   1.401 +    return SECFailure;
   1.402 +}
   1.403 +
   1.404 +SECStatus
   1.405 +CRMF_CertRequestSetTemplateField(CRMFCertRequest       *inCertReq, 
   1.406 +				 CRMFCertTemplateField  inTemplateField,
   1.407 +				 void                  *data)
   1.408 +{
   1.409 +    CRMFCertTemplate *certTemplate;
   1.410 +    PLArenaPool      *poolp;
   1.411 +    SECStatus         rv = SECFailure;
   1.412 +    void             *mark;
   1.413 +    
   1.414 +
   1.415 +    if (inCertReq == NULL) {
   1.416 +        return SECFailure;
   1.417 +    }
   1.418 +
   1.419 +    certTemplate = &(inCertReq->certTemplate);
   1.420 +
   1.421 +    poolp = inCertReq->poolp;
   1.422 +    mark = PORT_ArenaMark(poolp);
   1.423 +    switch (inTemplateField) {
   1.424 +    case crmfVersion:
   1.425 +      rv = crmf_template_add_version(poolp,&(certTemplate->version), 
   1.426 +				     *(long*)data);
   1.427 +      break;
   1.428 +    case crmfSerialNumber:
   1.429 +      rv = crmf_template_add_serialnumber(poolp, 
   1.430 +					  &(certTemplate->serialNumber),
   1.431 +					  *(long*)data);
   1.432 +      break;
   1.433 +    case crmfSigningAlg:
   1.434 +      rv = crmf_template_copy_secalg (poolp, &(certTemplate->signingAlg),
   1.435 +				      (SECAlgorithmID*)data);
   1.436 +      break;
   1.437 +    case crmfIssuer:
   1.438 +      rv = crmf_template_add_issuer (poolp, &(certTemplate->issuer), 
   1.439 +				     (CERTName*)data);
   1.440 +      break;
   1.441 +    case crmfValidity:
   1.442 +      rv = crmf_template_add_validity (poolp, &(certTemplate->validity),
   1.443 +				       (CRMFValidityCreationInfo*)data);
   1.444 +      break;
   1.445 +    case crmfSubject:
   1.446 +      rv = crmf_template_add_subject (poolp, &(certTemplate->subject),
   1.447 +				      (CERTName*)data);
   1.448 +      break;
   1.449 +    case crmfPublicKey:
   1.450 +      rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey),
   1.451 +					(CERTSubjectPublicKeyInfo*)data);
   1.452 +      break;
   1.453 +    case crmfIssuerUID:
   1.454 +      rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID),
   1.455 +					(SECItem*)data);
   1.456 +      break;
   1.457 +    case crmfSubjectUID:
   1.458 +      rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID),
   1.459 +					 (SECItem*)data);
   1.460 +      break;
   1.461 +    case crmfExtension:
   1.462 +      rv = crmf_template_add_extensions(poolp, certTemplate, 
   1.463 +					(CRMFCertExtCreationInfo*)data);
   1.464 +      break;
   1.465 +    }
   1.466 +    if (rv != SECSuccess) {
   1.467 +        PORT_ArenaRelease(poolp, mark);
   1.468 +    } else {
   1.469 +        PORT_ArenaUnmark(poolp, mark);
   1.470 +    }
   1.471 +    return rv;
   1.472 +}
   1.473 +
   1.474 +SECStatus
   1.475 +CRMF_CertReqMsgSetCertRequest (CRMFCertReqMsg  *inCertReqMsg, 
   1.476 +			       CRMFCertRequest *inCertReq)
   1.477 +{
   1.478 +    PORT_Assert (inCertReqMsg != NULL && inCertReq != NULL);
   1.479 +    if (inCertReqMsg == NULL || inCertReq == NULL) {
   1.480 +        return SECFailure;
   1.481 +    }
   1.482 +    inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp,
   1.483 +						   inCertReq);
   1.484 +    return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess;
   1.485 +}
   1.486 +
   1.487 +CRMFCertReqMsg*
   1.488 +CRMF_CreateCertReqMsg(void)
   1.489 +{
   1.490 +    PLArenaPool    *poolp;
   1.491 +    CRMFCertReqMsg *reqMsg;
   1.492 +
   1.493 +    poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
   1.494 +    if (poolp == NULL) {
   1.495 +        goto loser;
   1.496 +    }
   1.497 +    reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
   1.498 +    if (reqMsg == NULL) {
   1.499 +        goto loser;
   1.500 +    }
   1.501 +    reqMsg->poolp = poolp;
   1.502 +    return reqMsg;
   1.503 +    
   1.504 + loser:
   1.505 +    if (poolp) {
   1.506 +        PORT_FreeArena(poolp, PR_FALSE);
   1.507 +    }
   1.508 +    return NULL;
   1.509 +}
   1.510 +
   1.511 +SECStatus 
   1.512 +CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg)
   1.513 +{
   1.514 +    PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL);
   1.515 +    if (!inCertReqMsg->isDecoded) {
   1.516 +        if (inCertReqMsg->certReq->certTemplate.extensions != NULL) {
   1.517 +	    PORT_Free(inCertReqMsg->certReq->certTemplate.extensions);
   1.518 +	}
   1.519 +	if (inCertReqMsg->certReq->controls != NULL) {
   1.520 +	    PORT_Free(inCertReqMsg->certReq->controls);
   1.521 +	}
   1.522 +    }
   1.523 +    PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE);
   1.524 +    return SECSuccess;
   1.525 +}
   1.526 +
   1.527 +CRMFCertExtension*
   1.528 +crmf_create_cert_extension(PLArenaPool *poolp,
   1.529 +			   SECOidTag    id,
   1.530 +			   PRBool       isCritical,
   1.531 +			   SECItem     *data)
   1.532 +{
   1.533 +    CRMFCertExtension *newExt;
   1.534 +    SECOidData        *oidData;
   1.535 +    SECStatus          rv;
   1.536 +
   1.537 +    newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) :
   1.538 +                               PORT_ArenaZNew(poolp, CRMFCertExtension);
   1.539 +    if (newExt == NULL) {
   1.540 +        goto loser;
   1.541 +    }
   1.542 +    oidData = SECOID_FindOIDByTag(id);
   1.543 +    if (oidData == NULL || 
   1.544 +	oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) {
   1.545 +       goto loser;
   1.546 +    }
   1.547 +
   1.548 +    rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid));
   1.549 +    if (rv != SECSuccess) {
   1.550 +        goto loser;
   1.551 +    }
   1.552 +
   1.553 +    rv = SECITEM_CopyItem(poolp, &(newExt->value), data);
   1.554 +    if (rv != SECSuccess) {
   1.555 +        goto loser;
   1.556 +    }
   1.557 +
   1.558 +    if (isCritical) {
   1.559 +        newExt->critical.data = (poolp == NULL) ? 
   1.560 +	                                PORT_New(unsigned char) :
   1.561 +	                                PORT_ArenaNew(poolp, unsigned char);
   1.562 +	if (newExt->critical.data == NULL) {
   1.563 +	    goto loser;
   1.564 +	}
   1.565 +	newExt->critical.data[0] = hexTrue;
   1.566 +	newExt->critical.len = 1;
   1.567 +    }
   1.568 +    return newExt;
   1.569 + loser:
   1.570 +    if (newExt != NULL && poolp == NULL) {
   1.571 +        CRMF_DestroyCertExtension(newExt);
   1.572 +    }
   1.573 +    return NULL;
   1.574 +}
   1.575 +
   1.576 +CRMFCertExtension *
   1.577 +CRMF_CreateCertExtension(SECOidTag id,
   1.578 +			 PRBool    isCritical,
   1.579 +			 SECItem  *data) 
   1.580 +{
   1.581 +    return crmf_create_cert_extension(NULL, id, isCritical, data);
   1.582 +}
   1.583 +
   1.584 +static SECStatus
   1.585 +crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit)
   1.586 +{
   1.587 +    if (inExtension != NULL) {
   1.588 +        SECITEM_FreeItem (&(inExtension->id), PR_FALSE);
   1.589 +	SECITEM_FreeItem (&(inExtension->value), PR_FALSE);
   1.590 +	SECITEM_FreeItem (&(inExtension->critical), PR_FALSE);
   1.591 +	if (freeit) {
   1.592 +	    PORT_Free(inExtension);
   1.593 +	}
   1.594 +    }
   1.595 +    return SECSuccess;
   1.596 +}
   1.597 +
   1.598 +SECStatus
   1.599 +CRMF_DestroyCertExtension(CRMFCertExtension *inExtension)
   1.600 +{
   1.601 +    return crmf_destroy_cert_extension(inExtension, PR_TRUE);
   1.602 +}
   1.603 +
   1.604 +SECStatus
   1.605 +CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs) 
   1.606 +{
   1.607 +    PORT_Assert (inCertReqMsgs != NULL);
   1.608 +    if (inCertReqMsgs != NULL) {
   1.609 +        PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE);
   1.610 +    }
   1.611 +    return SECSuccess;
   1.612 +}
   1.613 +
   1.614 +static PRBool
   1.615 +crmf_item_has_data(SECItem *item)
   1.616 +{
   1.617 +    if (item != NULL && item->data != NULL) {
   1.618 +        return PR_TRUE;
   1.619 +    }
   1.620 +    return PR_FALSE;
   1.621 +}
   1.622 +
   1.623 +PRBool
   1.624 +CRMF_CertRequestIsFieldPresent(CRMFCertRequest       *inCertReq,
   1.625 +			       CRMFCertTemplateField  inTemplateField)
   1.626 +{
   1.627 +    PRBool             retVal;
   1.628 +    CRMFCertTemplate *certTemplate;
   1.629 +
   1.630 +    PORT_Assert(inCertReq != NULL);
   1.631 +    if (inCertReq == NULL) {
   1.632 +        /* This is probably some kind of error, but this is 
   1.633 +	 * the safest return value for this function.
   1.634 +	 */
   1.635 +        return PR_FALSE;
   1.636 +    }
   1.637 +    certTemplate = &inCertReq->certTemplate;
   1.638 +    switch (inTemplateField) {
   1.639 +    case crmfVersion:
   1.640 +      retVal = crmf_item_has_data(&certTemplate->version);
   1.641 +      break;
   1.642 +    case crmfSerialNumber:
   1.643 +      retVal = crmf_item_has_data(&certTemplate->serialNumber);
   1.644 +      break;
   1.645 +    case crmfSigningAlg:
   1.646 +      retVal = IS_NOT_NULL(certTemplate->signingAlg);
   1.647 +      break;
   1.648 +    case crmfIssuer:
   1.649 +      retVal = IS_NOT_NULL(certTemplate->issuer);
   1.650 +      break;
   1.651 +    case crmfValidity:
   1.652 +      retVal = IS_NOT_NULL(certTemplate->validity);
   1.653 +      break;
   1.654 +    case crmfSubject:
   1.655 +      retVal = IS_NOT_NULL(certTemplate->subject);
   1.656 +      break;
   1.657 +    case crmfPublicKey:
   1.658 +      retVal = IS_NOT_NULL(certTemplate->publicKey);
   1.659 +      break;
   1.660 +    case crmfIssuerUID:
   1.661 +      retVal = crmf_item_has_data(&certTemplate->issuerUID);
   1.662 +      break;
   1.663 +    case crmfSubjectUID:
   1.664 +      retVal = crmf_item_has_data(&certTemplate->subjectUID);
   1.665 +      break;
   1.666 +    case crmfExtension:
   1.667 +      retVal = IS_NOT_NULL(certTemplate->extensions);
   1.668 +      break;
   1.669 +    default:
   1.670 +      retVal = PR_FALSE;
   1.671 +    }
   1.672 +    return retVal;
   1.673 +}

mercurial