tor-browser

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

asn1cmn.c (7451B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "cmmf.h"
      6 #include "cmmfi.h"
      7 
      8 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
      9 SEC_ASN1_MKSUB(SEC_AnyTemplate)
     10 SEC_ASN1_MKSUB(SEC_IntegerTemplate)
     11 SEC_ASN1_MKSUB(SEC_SignedCertificateTemplate)
     12 
     13 static const SEC_ASN1Template CMMFCertResponseTemplate[] = {
     14    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertResponse) },
     15    { SEC_ASN1_INTEGER, offsetof(CMMFCertResponse, certReqId) },
     16    { SEC_ASN1_INLINE, offsetof(CMMFCertResponse, status),
     17      CMMFPKIStatusInfoTemplate },
     18    { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER,
     19      offsetof(CMMFCertResponse, certifiedKeyPair),
     20      CMMFCertifiedKeyPairTemplate },
     21    { 0 }
     22 };
     23 
     24 static const SEC_ASN1Template CMMFCertOrEncCertTemplate[] = {
     25    { SEC_ASN1_ANY, offsetof(CMMFCertOrEncCert, derValue), NULL,
     26      sizeof(CMMFCertOrEncCert) },
     27    { 0 }
     28 };
     29 
     30 const SEC_ASN1Template CMMFCertifiedKeyPairTemplate[] = {
     31    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertifiedKeyPair) },
     32    { SEC_ASN1_INLINE, offsetof(CMMFCertifiedKeyPair, certOrEncCert),
     33      CMMFCertOrEncCertTemplate },
     34    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 0,
     35      offsetof(CMMFCertifiedKeyPair, privateKey),
     36      CRMFEncryptedValueTemplate },
     37    { SEC_ASN1_NO_STREAM | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
     38          SEC_ASN1_XTRN | 1,
     39      offsetof(CMMFCertifiedKeyPair, derPublicationInfo),
     40      SEC_ASN1_SUB(SEC_AnyTemplate) },
     41    { 0 }
     42 };
     43 
     44 const SEC_ASN1Template CMMFPKIStatusInfoTemplate[] = {
     45    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFPKIStatusInfo) },
     46    { SEC_ASN1_INTEGER, offsetof(CMMFPKIStatusInfo, status) },
     47    { SEC_ASN1_OPTIONAL | SEC_ASN1_UTF8_STRING,
     48      offsetof(CMMFPKIStatusInfo, statusString) },
     49    { SEC_ASN1_OPTIONAL | SEC_ASN1_BIT_STRING,
     50      offsetof(CMMFPKIStatusInfo, failInfo) },
     51    { 0 }
     52 };
     53 
     54 const SEC_ASN1Template CMMFSequenceOfCertsTemplate[] = {
     55    { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0,
     56      SEC_ASN1_SUB(SEC_SignedCertificateTemplate) }
     57 };
     58 
     59 const SEC_ASN1Template CMMFRandTemplate[] = {
     60    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFRand) },
     61    { SEC_ASN1_INTEGER, offsetof(CMMFRand, integer) },
     62    { SEC_ASN1_OCTET_STRING, offsetof(CMMFRand, senderHash) },
     63    { 0 }
     64 };
     65 
     66 const SEC_ASN1Template CMMFPOPODecKeyRespContentTemplate[] = {
     67    { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
     68      offsetof(CMMFPOPODecKeyRespContent, responses),
     69      SEC_ASN1_SUB(SEC_IntegerTemplate),
     70      sizeof(CMMFPOPODecKeyRespContent) },
     71    { 0 }
     72 };
     73 
     74 const SEC_ASN1Template CMMFCertOrEncCertEncryptedCertTemplate[] = {
     75    { SEC_ASN1_CONTEXT_SPECIFIC | 1,
     76      0,
     77      CRMFEncryptedValueTemplate },
     78    { 0 }
     79 };
     80 
     81 const SEC_ASN1Template CMMFCertOrEncCertCertificateTemplate[] = {
     82    { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
     83      0,
     84      SEC_ASN1_SUB(SEC_SignedCertificateTemplate) },
     85    { 0 }
     86 };
     87 
     88 const SEC_ASN1Template CMMFCertRepContentTemplate[] = {
     89    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertRepContent) },
     90    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL |
     91          SEC_ASN1_CONTEXT_SPECIFIC | 1,
     92      offsetof(CMMFCertRepContent, caPubs),
     93      CMMFSequenceOfCertsTemplate },
     94    { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFCertRepContent, response),
     95      CMMFCertResponseTemplate },
     96    { 0 }
     97 };
     98 
     99 static const SEC_ASN1Template CMMFChallengeTemplate[] = {
    100    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFChallenge) },
    101    { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
    102      offsetof(CMMFChallenge, owf),
    103      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    104    { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, witness) },
    105    { SEC_ASN1_ANY, offsetof(CMMFChallenge, senderDER) },
    106    { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, key) },
    107    { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, challenge) },
    108    { 0 }
    109 };
    110 
    111 const SEC_ASN1Template CMMFPOPODecKeyChallContentTemplate[] = {
    112    { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFPOPODecKeyChallContent, challenges),
    113      CMMFChallengeTemplate, sizeof(CMMFPOPODecKeyChallContent) },
    114    { 0 }
    115 };
    116 
    117 SECStatus
    118 cmmf_decode_process_cert_response(PLArenaPool *poolp,
    119                                  CERTCertDBHandle *db,
    120                                  CMMFCertResponse *inCertResp)
    121 {
    122    SECStatus rv = SECSuccess;
    123 
    124    if (inCertResp->certifiedKeyPair != NULL) {
    125        rv = cmmf_decode_process_certified_key_pair(poolp,
    126                                                    db,
    127                                                    inCertResp->certifiedKeyPair);
    128    }
    129    return rv;
    130 }
    131 
    132 static CERTCertificate *
    133 cmmf_DecodeDERCertificate(CERTCertDBHandle *db, SECItem *derCert)
    134 {
    135    CERTCertificate *newCert;
    136 
    137    newCert = CERT_NewTempCertificate(db, derCert, NULL, PR_FALSE, PR_TRUE);
    138    return newCert;
    139 }
    140 
    141 static CMMFCertOrEncCertChoice
    142 cmmf_get_certorenccertchoice_from_der(SECItem *der)
    143 {
    144    CMMFCertOrEncCertChoice retChoice;
    145 
    146    switch (der->data[0] & 0x0f) {
    147        case 0:
    148            retChoice = cmmfCertificate;
    149            break;
    150        case 1:
    151            retChoice = cmmfEncryptedCert;
    152            break;
    153        default:
    154            retChoice = cmmfNoCertOrEncCert;
    155            break;
    156    }
    157    return retChoice;
    158 }
    159 
    160 static SECStatus
    161 cmmf_decode_process_certorenccert(PLArenaPool *poolp,
    162                                  CERTCertDBHandle *db,
    163                                  CMMFCertOrEncCert *inCertOrEncCert)
    164 {
    165    SECStatus rv = SECSuccess;
    166 
    167    inCertOrEncCert->choice =
    168        cmmf_get_certorenccertchoice_from_der(&inCertOrEncCert->derValue);
    169 
    170    switch (inCertOrEncCert->choice) {
    171        case cmmfCertificate: {
    172            /* The DER has implicit tagging, so we gotta switch it to
    173             * un-tagged in order for the ASN1 parser to understand it.
    174             * Saving the bits that were changed.
    175             */
    176            inCertOrEncCert->derValue.data[0] = 0x30;
    177            inCertOrEncCert->cert.certificate =
    178                cmmf_DecodeDERCertificate(db, &inCertOrEncCert->derValue);
    179            if (inCertOrEncCert->cert.certificate == NULL) {
    180                rv = SECFailure;
    181            }
    182 
    183        } break;
    184        case cmmfEncryptedCert:
    185            PORT_Assert(poolp);
    186            if (!poolp) {
    187                PORT_SetError(SEC_ERROR_INVALID_ARGS);
    188                rv = SECFailure;
    189                break;
    190            }
    191            inCertOrEncCert->cert.encryptedCert =
    192                PORT_ArenaZNew(poolp, CRMFEncryptedValue);
    193            if (inCertOrEncCert->cert.encryptedCert == NULL) {
    194                rv = SECFailure;
    195                break;
    196            }
    197            rv = SEC_ASN1Decode(poolp, inCertOrEncCert->cert.encryptedCert,
    198                                CMMFCertOrEncCertEncryptedCertTemplate,
    199                                (const char *)inCertOrEncCert->derValue.data,
    200                                inCertOrEncCert->derValue.len);
    201            break;
    202        default:
    203            rv = SECFailure;
    204    }
    205    return rv;
    206 }
    207 
    208 SECStatus
    209 cmmf_decode_process_certified_key_pair(PLArenaPool *poolp,
    210                                       CERTCertDBHandle *db,
    211                                       CMMFCertifiedKeyPair *inCertKeyPair)
    212 {
    213    return cmmf_decode_process_certorenccert(poolp,
    214                                             db,
    215                                             &inCertKeyPair->certOrEncCert);
    216 }