tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

crmfget.c (12435B)


      1 /* -*- Mode: C; tab-width: 8 -*-*/
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "crmf.h"
      7 #include "crmfi.h"
      8 #include "keyhi.h"
      9 #include "secder.h"
     10 
     11 CRMFPOPChoice
     12 CRMF_CertReqMsgGetPOPType(CRMFCertReqMsg *inCertReqMsg)
     13 {
     14    PORT_Assert(inCertReqMsg != NULL);
     15    if (inCertReqMsg != NULL && inCertReqMsg->pop != NULL) {
     16        return inCertReqMsg->pop->popUsed;
     17    }
     18    return crmfNoPOPChoice;
     19 }
     20 
     21 static SECStatus
     22 crmf_destroy_validity(CRMFOptionalValidity *inValidity, PRBool freeit)
     23 {
     24    if (inValidity != NULL) {
     25        if (inValidity->notBefore.data != NULL) {
     26            PORT_Free(inValidity->notBefore.data);
     27        }
     28        if (inValidity->notAfter.data != NULL) {
     29            PORT_Free(inValidity->notAfter.data);
     30        }
     31        if (freeit) {
     32            PORT_Free(inValidity);
     33        }
     34    }
     35    return SECSuccess;
     36 }
     37 
     38 static SECStatus
     39 crmf_copy_cert_request_validity(PLArenaPool *poolp,
     40                                CRMFOptionalValidity **destValidity,
     41                                CRMFOptionalValidity *srcValidity)
     42 {
     43    CRMFOptionalValidity *myValidity = NULL;
     44    SECStatus rv;
     45 
     46    *destValidity = myValidity = (poolp == NULL) ? PORT_ZNew(CRMFOptionalValidity)
     47                                                 : PORT_ArenaZNew(poolp, CRMFOptionalValidity);
     48    if (myValidity == NULL) {
     49        goto loser;
     50    }
     51    if (srcValidity->notBefore.data != NULL) {
     52        rv = SECITEM_CopyItem(poolp, &myValidity->notBefore,
     53                              &srcValidity->notBefore);
     54        if (rv != SECSuccess) {
     55            goto loser;
     56        }
     57    }
     58    if (srcValidity->notAfter.data != NULL) {
     59        rv = SECITEM_CopyItem(poolp, &myValidity->notAfter,
     60                              &srcValidity->notAfter);
     61        if (rv != SECSuccess) {
     62            goto loser;
     63        }
     64    }
     65    return SECSuccess;
     66 loser:
     67    if (myValidity != NULL && poolp == NULL) {
     68        crmf_destroy_validity(myValidity, PR_TRUE);
     69    }
     70    return SECFailure;
     71 }
     72 
     73 static SECStatus
     74 crmf_copy_extensions(PLArenaPool *poolp,
     75                     CRMFCertTemplate *destTemplate,
     76                     CRMFCertExtension **srcExt)
     77 {
     78    int numExt = 0, i;
     79    CRMFCertExtension **myExtArray = NULL;
     80 
     81    while (srcExt[numExt] != NULL) {
     82        numExt++;
     83    }
     84    if (numExt == 0) {
     85        /*No extensions to copy.*/
     86        destTemplate->extensions = NULL;
     87        destTemplate->numExtensions = 0;
     88        return SECSuccess;
     89    }
     90    destTemplate->extensions = myExtArray =
     91        PORT_NewArray(CRMFCertExtension *, numExt + 1);
     92    if (myExtArray == NULL) {
     93        goto loser;
     94    }
     95 
     96    for (i = 0; i < numExt; i++) {
     97        myExtArray[i] = crmf_copy_cert_extension(poolp, srcExt[i]);
     98        if (myExtArray[i] == NULL) {
     99            goto loser;
    100        }
    101    }
    102    destTemplate->numExtensions = numExt;
    103    myExtArray[numExt] = NULL;
    104    return SECSuccess;
    105 loser:
    106    if (myExtArray != NULL) {
    107        if (poolp == NULL) {
    108            for (i = 0; myExtArray[i] != NULL; i++) {
    109                CRMF_DestroyCertExtension(myExtArray[i]);
    110            }
    111        }
    112        PORT_Free(myExtArray);
    113    }
    114    destTemplate->extensions = NULL;
    115    destTemplate->numExtensions = 0;
    116    return SECFailure;
    117 }
    118 
    119 static SECStatus
    120 crmf_copy_cert_request_template(PLArenaPool *poolp,
    121                                CRMFCertTemplate *destTemplate,
    122                                CRMFCertTemplate *srcTemplate)
    123 {
    124    SECStatus rv;
    125 
    126    if (srcTemplate->version.data != NULL) {
    127        rv = SECITEM_CopyItem(poolp, &destTemplate->version,
    128                              &srcTemplate->version);
    129        if (rv != SECSuccess) {
    130            goto loser;
    131        }
    132    }
    133    if (srcTemplate->serialNumber.data != NULL) {
    134        rv = SECITEM_CopyItem(poolp, &destTemplate->serialNumber,
    135                              &srcTemplate->serialNumber);
    136        if (rv != SECSuccess) {
    137            goto loser;
    138        }
    139    }
    140    if (srcTemplate->signingAlg != NULL) {
    141        rv = crmf_template_copy_secalg(poolp, &destTemplate->signingAlg,
    142                                       srcTemplate->signingAlg);
    143        if (rv != SECSuccess) {
    144            goto loser;
    145        }
    146    }
    147    if (srcTemplate->issuer != NULL) {
    148        rv = crmf_copy_cert_name(poolp, &destTemplate->issuer,
    149                                 srcTemplate->issuer);
    150        if (rv != SECSuccess) {
    151            goto loser;
    152        }
    153    }
    154    if (srcTemplate->validity != NULL) {
    155        rv = crmf_copy_cert_request_validity(poolp, &destTemplate->validity,
    156                                             srcTemplate->validity);
    157        if (rv != SECSuccess) {
    158            goto loser;
    159        }
    160    }
    161    if (srcTemplate->subject != NULL) {
    162        rv = crmf_copy_cert_name(poolp, &destTemplate->subject,
    163                                 srcTemplate->subject);
    164        if (rv != SECSuccess) {
    165            goto loser;
    166        }
    167    }
    168    if (srcTemplate->publicKey != NULL) {
    169        rv = crmf_template_add_public_key(poolp, &destTemplate->publicKey,
    170                                          srcTemplate->publicKey);
    171        if (rv != SECSuccess) {
    172            goto loser;
    173        }
    174    }
    175    if (srcTemplate->issuerUID.data != NULL) {
    176        rv = crmf_make_bitstring_copy(poolp, &destTemplate->issuerUID,
    177                                      &srcTemplate->issuerUID);
    178        if (rv != SECSuccess) {
    179            goto loser;
    180        }
    181    }
    182    if (srcTemplate->subjectUID.data != NULL) {
    183        rv = crmf_make_bitstring_copy(poolp, &destTemplate->subjectUID,
    184                                      &srcTemplate->subjectUID);
    185        if (rv != SECSuccess) {
    186            goto loser;
    187        }
    188    }
    189    if (srcTemplate->extensions != NULL) {
    190        rv = crmf_copy_extensions(poolp, destTemplate,
    191                                  srcTemplate->extensions);
    192        if (rv != SECSuccess) {
    193            goto loser;
    194        }
    195    }
    196    return SECSuccess;
    197 loser:
    198    return SECFailure;
    199 }
    200 
    201 static CRMFControl *
    202 crmf_copy_control(PLArenaPool *poolp, CRMFControl *srcControl)
    203 {
    204    CRMFControl *newControl;
    205    SECStatus rv;
    206 
    207    newControl = (poolp == NULL) ? PORT_ZNew(CRMFControl) : PORT_ArenaZNew(poolp, CRMFControl);
    208    if (newControl == NULL) {
    209        goto loser;
    210    }
    211    newControl->tag = srcControl->tag;
    212    rv = SECITEM_CopyItem(poolp, &newControl->derTag, &srcControl->derTag);
    213    if (rv != SECSuccess) {
    214        goto loser;
    215    }
    216    rv = SECITEM_CopyItem(poolp, &newControl->derValue, &srcControl->derValue);
    217    if (rv != SECSuccess) {
    218        goto loser;
    219    }
    220    /* We only handle PKIArchiveOptions Control right now.  But if in
    221     * the future, more controls that are part of the union are added,
    222     * then they need to be handled here as well.
    223     */
    224    switch (newControl->tag) {
    225        case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
    226            rv = crmf_copy_pkiarchiveoptions(poolp,
    227                                             &newControl->value.archiveOptions,
    228                                             &srcControl->value.archiveOptions);
    229            break;
    230        default:
    231            rv = SECSuccess;
    232    }
    233    if (rv != SECSuccess) {
    234        goto loser;
    235    }
    236    return newControl;
    237 
    238 loser:
    239    if (poolp == NULL && newControl != NULL) {
    240        CRMF_DestroyControl(newControl);
    241    }
    242    return NULL;
    243 }
    244 
    245 static SECStatus
    246 crmf_copy_cert_request_controls(PLArenaPool *poolp,
    247                                CRMFCertRequest *destReq,
    248                                CRMFCertRequest *srcReq)
    249 {
    250    int numControls, i;
    251    CRMFControl **myControls = NULL;
    252 
    253    numControls = CRMF_CertRequestGetNumControls(srcReq);
    254    if (numControls == 0) {
    255        /* No Controls To Copy*/
    256        return SECSuccess;
    257    }
    258    myControls = destReq->controls = PORT_NewArray(CRMFControl *,
    259                                                   numControls + 1);
    260    if (myControls == NULL) {
    261        goto loser;
    262    }
    263    for (i = 0; i < numControls; i++) {
    264        myControls[i] = crmf_copy_control(poolp, srcReq->controls[i]);
    265        if (myControls[i] == NULL) {
    266            goto loser;
    267        }
    268    }
    269    myControls[numControls] = NULL;
    270    return SECSuccess;
    271 loser:
    272    if (myControls != NULL) {
    273        if (poolp == NULL) {
    274            for (i = 0; myControls[i] != NULL; i++) {
    275                CRMF_DestroyControl(myControls[i]);
    276            }
    277        }
    278        PORT_Free(myControls);
    279    }
    280    return SECFailure;
    281 }
    282 
    283 CRMFCertRequest *
    284 crmf_copy_cert_request(PLArenaPool *poolp, CRMFCertRequest *srcReq)
    285 {
    286    CRMFCertRequest *newReq = NULL;
    287    SECStatus rv;
    288 
    289    if (srcReq == NULL) {
    290        return NULL;
    291    }
    292    newReq = (poolp == NULL) ? PORT_ZNew(CRMFCertRequest) : PORT_ArenaZNew(poolp, CRMFCertRequest);
    293    if (newReq == NULL) {
    294        goto loser;
    295    }
    296    rv = SECITEM_CopyItem(poolp, &newReq->certReqId, &srcReq->certReqId);
    297    if (rv != SECSuccess) {
    298        goto loser;
    299    }
    300    rv = crmf_copy_cert_request_template(poolp, &newReq->certTemplate,
    301                                         &srcReq->certTemplate);
    302    if (rv != SECSuccess) {
    303        goto loser;
    304    }
    305    rv = crmf_copy_cert_request_controls(poolp, newReq, srcReq);
    306    if (rv != SECSuccess) {
    307        goto loser;
    308    }
    309    return newReq;
    310 loser:
    311    if (newReq != NULL && poolp == NULL) {
    312        CRMF_DestroyCertRequest(newReq);
    313        PORT_Free(newReq);
    314    }
    315    return NULL;
    316 }
    317 
    318 SECStatus
    319 CRMF_DestroyGetValidity(CRMFGetValidity *inValidity)
    320 {
    321    PORT_Assert(inValidity != NULL);
    322    if (inValidity != NULL) {
    323        if (inValidity->notAfter) {
    324            PORT_Free(inValidity->notAfter);
    325            inValidity->notAfter = NULL;
    326        }
    327        if (inValidity->notBefore) {
    328            PORT_Free(inValidity->notBefore);
    329            inValidity->notBefore = NULL;
    330        }
    331    }
    332    return SECSuccess;
    333 }
    334 
    335 SECStatus
    336 crmf_make_bitstring_copy(PLArenaPool *arena, SECItem *dest, SECItem *src)
    337 {
    338    int origLenBits;
    339    int bytesToCopy;
    340    SECStatus rv;
    341 
    342    origLenBits = src->len;
    343    bytesToCopy = CRMF_BITS_TO_BYTES(origLenBits);
    344    src->len = bytesToCopy;
    345    rv = SECITEM_CopyItem(arena, dest, src);
    346    src->len = origLenBits;
    347    if (rv != SECSuccess) {
    348        return rv;
    349    }
    350    dest->len = origLenBits;
    351    return SECSuccess;
    352 }
    353 
    354 int
    355 CRMF_CertRequestGetNumberOfExtensions(CRMFCertRequest *inCertReq)
    356 {
    357    CRMFCertTemplate *certTemplate;
    358    int count = 0;
    359 
    360    certTemplate = &inCertReq->certTemplate;
    361    if (certTemplate->extensions) {
    362        while (certTemplate->extensions[count] != NULL)
    363            count++;
    364    }
    365    return count;
    366 }
    367 
    368 SECOidTag
    369 CRMF_CertExtensionGetOidTag(CRMFCertExtension *inExtension)
    370 {
    371    PORT_Assert(inExtension != NULL);
    372    if (inExtension == NULL) {
    373        return SEC_OID_UNKNOWN;
    374    }
    375    return SECOID_FindOIDTag(&inExtension->id);
    376 }
    377 
    378 PRBool
    379 CRMF_CertExtensionGetIsCritical(CRMFCertExtension *inExt)
    380 {
    381    PORT_Assert(inExt != NULL);
    382    if (inExt == NULL) {
    383        return PR_FALSE;
    384    }
    385    return inExt->critical.data != NULL;
    386 }
    387 
    388 SECItem *
    389 CRMF_CertExtensionGetValue(CRMFCertExtension *inExtension)
    390 {
    391    PORT_Assert(inExtension != NULL);
    392    if (inExtension == NULL) {
    393        return NULL;
    394    }
    395 
    396    return SECITEM_DupItem(&inExtension->value);
    397 }
    398 
    399 SECStatus
    400 CRMF_DestroyPOPOSigningKey(CRMFPOPOSigningKey *inKey)
    401 {
    402    PORT_Assert(inKey != NULL);
    403    if (inKey != NULL) {
    404        if (inKey->derInput.data != NULL) {
    405            SECITEM_FreeItem(&inKey->derInput, PR_FALSE);
    406        }
    407        if (inKey->algorithmIdentifier != NULL) {
    408            SECOID_DestroyAlgorithmID(inKey->algorithmIdentifier, PR_TRUE);
    409        }
    410        if (inKey->signature.data != NULL) {
    411            SECITEM_FreeItem(&inKey->signature, PR_FALSE);
    412        }
    413        PORT_Free(inKey);
    414    }
    415    return SECSuccess;
    416 }
    417 
    418 SECStatus
    419 CRMF_DestroyPOPOPrivKey(CRMFPOPOPrivKey *inPrivKey)
    420 {
    421    PORT_Assert(inPrivKey != NULL);
    422    if (inPrivKey != NULL) {
    423        SECITEM_FreeItem(&inPrivKey->message.thisMessage, PR_FALSE);
    424        PORT_Free(inPrivKey);
    425    }
    426    return SECSuccess;
    427 }
    428 
    429 int
    430 CRMF_CertRequestGetNumControls(CRMFCertRequest *inCertReq)
    431 {
    432    int count = 0;
    433 
    434    PORT_Assert(inCertReq != NULL);
    435    if (inCertReq == NULL) {
    436        return 0;
    437    }
    438    if (inCertReq->controls) {
    439        while (inCertReq->controls[count] != NULL)
    440            count++;
    441    }
    442    return count;
    443 }