tor-browser

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

pkix_trustanchor.c (15678B)


      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 * pkix_trustanchor.c
      6 *
      7 * TrustAnchor Object Functions
      8 *
      9 */
     10 
     11 #include "pkix_trustanchor.h"
     12 
     13 /* --Private-Functions-------------------------------------------- */
     14 
     15 /*
     16 * FUNCTION: pkix_TrustAnchor_Destroy
     17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
     18 */
     19 static PKIX_Error *
     20 pkix_TrustAnchor_Destroy(
     21        PKIX_PL_Object *object,
     22        void *plContext)
     23 {
     24        PKIX_TrustAnchor *anchor = NULL;
     25 
     26        PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Destroy");
     27        PKIX_NULLCHECK_ONE(object);
     28 
     29        /* Check that this object is a trust anchor */
     30        PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext),
     31                    PKIX_OBJECTNOTTRUSTANCHOR);
     32 
     33        anchor = (PKIX_TrustAnchor *)object;
     34 
     35        PKIX_DECREF(anchor->trustedCert);
     36        PKIX_DECREF(anchor->caName);
     37        PKIX_DECREF(anchor->caPubKey);
     38        PKIX_DECREF(anchor->nameConstraints);
     39 
     40 cleanup:
     41 
     42        PKIX_RETURN(TRUSTANCHOR);
     43 }
     44 
     45 /*
     46 * FUNCTION: pkix_TrustAnchor_Equals
     47 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
     48 */
     49 static PKIX_Error *
     50 pkix_TrustAnchor_Equals(
     51        PKIX_PL_Object *first,
     52        PKIX_PL_Object *second,
     53        PKIX_Boolean *pResult,
     54        void *plContext)
     55 {
     56        PKIX_UInt32 secondType;
     57        PKIX_Boolean cmpResult;
     58        PKIX_TrustAnchor *firstAnchor = NULL;
     59        PKIX_TrustAnchor *secondAnchor = NULL;
     60        PKIX_PL_Cert *firstCert = NULL;
     61        PKIX_PL_Cert *secondCert = NULL;
     62 
     63        PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Equals");
     64        PKIX_NULLCHECK_THREE(first, second, pResult);
     65 
     66        PKIX_CHECK(pkix_CheckType(first, PKIX_TRUSTANCHOR_TYPE, plContext),
     67                    PKIX_FIRSTOBJECTNOTTRUSTANCHOR);
     68 
     69        PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
     70                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
     71 
     72        *pResult = PKIX_FALSE;
     73 
     74        if (secondType != PKIX_TRUSTANCHOR_TYPE) goto cleanup;
     75 
     76        firstAnchor = (PKIX_TrustAnchor *)first;
     77        secondAnchor = (PKIX_TrustAnchor *)second;
     78 
     79        firstCert = firstAnchor->trustedCert;
     80        secondCert = secondAnchor->trustedCert;
     81 
     82        if ((firstCert && !secondCert) || (!firstCert && secondCert)){
     83                goto cleanup;
     84        }
     85 
     86        if (firstCert && secondCert){
     87                PKIX_CHECK(PKIX_PL_Object_Equals
     88                            ((PKIX_PL_Object *)firstCert,
     89                            (PKIX_PL_Object *)secondCert,
     90                            &cmpResult,
     91                            plContext),
     92                            PKIX_OBJECTEQUALSFAILED);
     93        } else {
     94                PKIX_CHECK(PKIX_PL_Object_Equals
     95                            ((PKIX_PL_Object *)firstAnchor->caName,
     96                            (PKIX_PL_Object *)secondAnchor->caName,
     97                            &cmpResult,
     98                            plContext),
     99                            PKIX_OBJECTEQUALSFAILED);
    100 
    101                if (!cmpResult) goto cleanup;
    102 
    103                PKIX_CHECK(PKIX_PL_Object_Equals
    104                            ((PKIX_PL_Object *)firstAnchor->caPubKey,
    105                            (PKIX_PL_Object *)secondAnchor->caPubKey,
    106                            &cmpResult,
    107                            plContext),
    108                            PKIX_OBJECTEQUALSFAILED);
    109 
    110                if (!cmpResult) goto cleanup;
    111 
    112                PKIX_EQUALS
    113                        (firstAnchor->nameConstraints,
    114                        secondAnchor->nameConstraints,
    115                        &cmpResult,
    116                        plContext,
    117                        PKIX_OBJECTEQUALSFAILED);
    118 
    119                if (!cmpResult) goto cleanup;
    120 
    121        }
    122 
    123        *pResult = cmpResult;
    124 
    125 cleanup:
    126 
    127        PKIX_RETURN(TRUSTANCHOR);
    128 }
    129 
    130 /*
    131 * FUNCTION: pkix_TrustAnchor_Hashcode
    132 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
    133 */
    134 static PKIX_Error *
    135 pkix_TrustAnchor_Hashcode(
    136        PKIX_PL_Object *object,
    137        PKIX_UInt32 *pHashcode,
    138        void *plContext)
    139 {
    140        PKIX_TrustAnchor *anchor = NULL;
    141        PKIX_PL_Cert *cert = NULL;
    142        PKIX_UInt32 hash = 0;
    143        PKIX_UInt32 certHash = 0;
    144        PKIX_UInt32 nameHash = 0;
    145        PKIX_UInt32 pubKeyHash = 0;
    146        PKIX_UInt32 ncHash = 0;
    147 
    148        PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Hashcode");
    149        PKIX_NULLCHECK_TWO(object, pHashcode);
    150 
    151        PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext),
    152                    PKIX_OBJECTNOTTRUSTANCHOR);
    153 
    154        anchor = (PKIX_TrustAnchor*)object;
    155        cert = anchor->trustedCert;
    156 
    157        if (cert){
    158                PKIX_CHECK(PKIX_PL_Object_Hashcode
    159                            ((PKIX_PL_Object *)cert,
    160                            &certHash,
    161                            plContext),
    162                            PKIX_OBJECTHASHCODEFAILED);
    163 
    164                hash = certHash;
    165 
    166        } else {
    167                PKIX_CHECK(PKIX_PL_Object_Hashcode
    168                            ((PKIX_PL_Object *)anchor->caName,
    169                            &nameHash,
    170                            plContext),
    171                            PKIX_OBJECTHASHCODEFAILED);
    172 
    173                PKIX_CHECK(PKIX_PL_Object_Hashcode
    174                            ((PKIX_PL_Object *)anchor->caPubKey,
    175                            &pubKeyHash,
    176                            plContext),
    177                            PKIX_OBJECTHASHCODEFAILED);
    178 
    179                PKIX_HASHCODE(anchor->nameConstraints, &ncHash, plContext,
    180                        PKIX_OBJECTHASHCODEFAILED);
    181 
    182                hash = 31 * nameHash + pubKeyHash + ncHash;
    183 
    184        }
    185 
    186        *pHashcode = hash;
    187 
    188 cleanup:
    189 
    190        PKIX_RETURN(TRUSTANCHOR);
    191 }
    192 
    193 /*
    194 * FUNCTION: pkix_TrustAnchor_ToString
    195 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
    196 */
    197 static PKIX_Error *
    198 pkix_TrustAnchor_ToString(
    199        PKIX_PL_Object *object,
    200        PKIX_PL_String **pString,
    201        void *plContext)
    202 {
    203        PKIX_TrustAnchor *anchor = NULL;
    204        char *asciiFormat = NULL;
    205        PKIX_PL_String *formatString = NULL;
    206        PKIX_PL_String *anchorString = NULL;
    207        PKIX_PL_String *certString = NULL;
    208        PKIX_PL_String *nameString = NULL;
    209        PKIX_PL_String *pubKeyString = NULL;
    210        PKIX_PL_String *nameConstraintsString = NULL;
    211 
    212        PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_ToString");
    213        PKIX_NULLCHECK_TWO(object, pString);
    214 
    215        PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext),
    216                    PKIX_OBJECTNOTTRUSTANCHOR);
    217 
    218        anchor = (PKIX_TrustAnchor*)object;
    219 
    220        if (anchor->trustedCert){
    221                asciiFormat =
    222                        "[\n"
    223                        "\tTrusted Cert:	%s\n"
    224                        "]\n";
    225 
    226                PKIX_CHECK(PKIX_PL_String_Create
    227                            (PKIX_ESCASCII,
    228                            asciiFormat,
    229                            0,
    230                            &formatString,
    231                            plContext),
    232                            PKIX_STRINGCREATEFAILED);
    233 
    234                PKIX_CHECK(PKIX_PL_Object_ToString
    235                            ((PKIX_PL_Object *)anchor->trustedCert,
    236                            &certString,
    237                            plContext),
    238                            PKIX_OBJECTTOSTRINGFAILED);
    239 
    240                PKIX_CHECK(PKIX_PL_Sprintf
    241                            (&anchorString,
    242                            plContext,
    243                            formatString,
    244                            certString),
    245                            PKIX_SPRINTFFAILED);
    246        } else {
    247                asciiFormat =
    248                        "[\n"
    249                        "\tTrusted CA Name:         %s\n"
    250                        "\tTrusted CA PublicKey:    %s\n"
    251                        "\tInitial Name Constraints:%s\n"
    252                        "]\n";
    253 
    254                PKIX_CHECK(PKIX_PL_String_Create
    255                            (PKIX_ESCASCII,
    256                            asciiFormat,
    257                            0,
    258                            &formatString,
    259                            plContext),
    260                            PKIX_STRINGCREATEFAILED);
    261 
    262                PKIX_CHECK(PKIX_PL_Object_ToString
    263                            ((PKIX_PL_Object *)anchor->caName,
    264                            &nameString,
    265                            plContext),
    266                            PKIX_OBJECTTOSTRINGFAILED);
    267 
    268                PKIX_CHECK(PKIX_PL_Object_ToString
    269                            ((PKIX_PL_Object *)anchor->caPubKey,
    270                            &pubKeyString,
    271                            plContext),
    272                            PKIX_OBJECTTOSTRINGFAILED);
    273 
    274                PKIX_TOSTRING
    275                        (anchor->nameConstraints,
    276                        &nameConstraintsString,
    277                        plContext,
    278                        PKIX_OBJECTTOSTRINGFAILED);
    279 
    280                PKIX_CHECK(PKIX_PL_Sprintf
    281                            (&anchorString,
    282                            plContext,
    283                            formatString,
    284                            nameString,
    285                            pubKeyString,
    286                            nameConstraintsString),
    287                            PKIX_SPRINTFFAILED);
    288        }
    289 
    290        *pString = anchorString;
    291 
    292 cleanup:
    293 
    294        PKIX_DECREF(formatString);
    295        PKIX_DECREF(certString);
    296        PKIX_DECREF(nameString);
    297        PKIX_DECREF(pubKeyString);
    298        PKIX_DECREF(nameConstraintsString);
    299 
    300        PKIX_RETURN(TRUSTANCHOR);
    301 }
    302 
    303 /*
    304 * FUNCTION: pkix_TrustAnchor_RegisterSelf
    305 * DESCRIPTION:
    306 *  Registers PKIX_TRUSTANCHOR_TYPE and its related functions with
    307 *  systemClasses[]
    308 * THREAD SAFETY:
    309 *  Not Thread Safe - for performance and complexity reasons
    310 *
    311 *  Since this function is only called by PKIX_PL_Initialize, which should
    312 *  only be called once, it is acceptable that this function is not
    313 *  thread-safe.
    314 */
    315 PKIX_Error *
    316 pkix_TrustAnchor_RegisterSelf(void *plContext)
    317 {
    318        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    319        pkix_ClassTable_Entry entry;
    320 
    321        PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_RegisterSelf");
    322 
    323        entry.description = "TrustAnchor";
    324        entry.objCounter = 0;
    325        entry.typeObjectSize = sizeof(PKIX_TrustAnchor);
    326        entry.destructor = pkix_TrustAnchor_Destroy;
    327        entry.equalsFunction = pkix_TrustAnchor_Equals;
    328        entry.hashcodeFunction = pkix_TrustAnchor_Hashcode;
    329        entry.toStringFunction = pkix_TrustAnchor_ToString;
    330        entry.comparator = NULL;
    331        entry.duplicateFunction = pkix_duplicateImmutable;
    332 
    333        systemClasses[PKIX_TRUSTANCHOR_TYPE] = entry;
    334 
    335        PKIX_RETURN(TRUSTANCHOR);
    336 }
    337 
    338 /* --Public-Functions--------------------------------------------- */
    339 
    340 
    341 /*
    342 * FUNCTION: PKIX_TrustAnchor_CreateWithCert (see comments in pkix_params.h)
    343 */
    344 PKIX_Error *
    345 PKIX_TrustAnchor_CreateWithCert(
    346        PKIX_PL_Cert *cert,
    347        PKIX_TrustAnchor **pAnchor,
    348        void *plContext)
    349 {
    350        PKIX_TrustAnchor *anchor = NULL;
    351 
    352        PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithCert");
    353        PKIX_NULLCHECK_TWO(cert, pAnchor);
    354 
    355        PKIX_CHECK(PKIX_PL_Object_Alloc
    356                    (PKIX_TRUSTANCHOR_TYPE,
    357                    sizeof (PKIX_TrustAnchor),
    358                    (PKIX_PL_Object **)&anchor,
    359                    plContext),
    360                    PKIX_COULDNOTCREATETRUSTANCHOROBJECT);
    361 
    362        /* initialize fields */
    363        PKIX_CHECK(
    364            PKIX_PL_Cert_SetAsTrustAnchor(cert, plContext),
    365            PKIX_CERTSETASTRUSTANCHORFAILED);
    366 
    367        PKIX_INCREF(cert);
    368        anchor->trustedCert = cert;
    369 
    370        anchor->caName = NULL;
    371        anchor->caPubKey = NULL;
    372 
    373        PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
    374                    (anchor->trustedCert, &anchor->nameConstraints, plContext),
    375                    PKIX_CERTGETNAMECONSTRAINTSFAILED);
    376 
    377 
    378        *pAnchor = anchor;
    379        anchor = NULL;
    380 
    381 cleanup:
    382 
    383        PKIX_DECREF(anchor);
    384 
    385        PKIX_RETURN(TRUSTANCHOR);
    386 
    387 }
    388 
    389 /*
    390 * FUNCTION: PKIX_TrustAnchor_CreateWithNameKeyPair
    391 *      (see comments in pkix_params.h)
    392 */
    393 PKIX_Error *
    394 PKIX_TrustAnchor_CreateWithNameKeyPair(
    395        PKIX_PL_X500Name *name,
    396        PKIX_PL_PublicKey *pubKey,
    397        PKIX_PL_CertNameConstraints *nameConstraints,
    398        PKIX_TrustAnchor **pAnchor,
    399        void *plContext)
    400 {
    401        PKIX_TrustAnchor *anchor = NULL;
    402 
    403        PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithNameKeyPair");
    404 
    405 #ifndef BUILD_LIBPKIX_TESTS
    406        /* Nss creates trust anchors by using PKIX_TrustAnchor_CreateWithCert
    407         * function as the complete trusted cert structure, and not only cert
    408         * public key, is required for chain building and validation processes. 
    409         * Restricting this function for been used only in libpkix unit
    410         * tests. */
    411        PKIX_ERROR(PKIX_FUNCTIONMUSTNOTBEUSED);
    412 #endif
    413 
    414        PKIX_NULLCHECK_THREE(name, pubKey, pAnchor);
    415 
    416        PKIX_CHECK(PKIX_PL_Object_Alloc
    417                    (PKIX_TRUSTANCHOR_TYPE,
    418                    sizeof (PKIX_TrustAnchor),
    419                    (PKIX_PL_Object **)&anchor,
    420                    plContext),
    421                    PKIX_COULDNOTCREATETRUSTANCHOROBJECT);
    422 
    423        /* initialize fields */
    424        anchor->trustedCert = NULL;
    425 
    426        PKIX_INCREF(name);
    427        anchor->caName = name;
    428 
    429        PKIX_INCREF(pubKey);
    430        anchor->caPubKey = pubKey;
    431 
    432        PKIX_INCREF(nameConstraints);
    433        anchor->nameConstraints = nameConstraints;
    434 
    435        *pAnchor = anchor;
    436        anchor = NULL;
    437 cleanup:
    438 
    439        PKIX_DECREF(anchor);
    440 
    441        PKIX_RETURN(TRUSTANCHOR);
    442 }
    443 
    444 /*
    445 * FUNCTION: PKIX_TrustAnchor_GetTrustedCert (see comments in pkix_params.h)
    446 */
    447 PKIX_Error *
    448 PKIX_TrustAnchor_GetTrustedCert(
    449        PKIX_TrustAnchor *anchor,
    450        PKIX_PL_Cert **pCert,
    451        void *plContext)
    452 {
    453        PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetTrustedCert");
    454        PKIX_NULLCHECK_TWO(anchor, pCert);
    455 
    456        PKIX_INCREF(anchor->trustedCert);
    457 
    458        *pCert = anchor->trustedCert;
    459 
    460 cleanup:
    461        PKIX_RETURN(TRUSTANCHOR);
    462 
    463 }
    464 
    465 /*
    466 * FUNCTION: PKIX_TrustAnchor_GetCAName (see comments in pkix_params.h)
    467 */
    468 PKIX_Error *
    469 PKIX_TrustAnchor_GetCAName(
    470        PKIX_TrustAnchor *anchor,
    471        PKIX_PL_X500Name **pCAName,
    472        void *plContext)
    473 {
    474        PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetCAName");
    475        PKIX_NULLCHECK_TWO(anchor, pCAName);
    476 
    477        PKIX_INCREF(anchor->caName);
    478 
    479        *pCAName = anchor->caName;
    480 
    481 cleanup:
    482        PKIX_RETURN(TRUSTANCHOR);
    483 
    484 }
    485 
    486 /*
    487 * FUNCTION: PKIX_TrustAnchor_GetCAPublicKey (see comments in pkix_params.h)
    488 */
    489 PKIX_Error *
    490 PKIX_TrustAnchor_GetCAPublicKey(
    491        PKIX_TrustAnchor *anchor,
    492        PKIX_PL_PublicKey **pPubKey,
    493        void *plContext)
    494 {
    495        PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetCAPublicKey");
    496        PKIX_NULLCHECK_TWO(anchor, pPubKey);
    497 
    498        PKIX_INCREF(anchor->caPubKey);
    499 
    500        *pPubKey = anchor->caPubKey;
    501 
    502 cleanup:
    503        PKIX_RETURN(TRUSTANCHOR);
    504 }
    505 
    506 /*
    507 * FUNCTION: PKIX_TrustAnchor_GetNameConstraints
    508 *      (see comments in pkix_params.h)
    509 */
    510 PKIX_Error *
    511 PKIX_TrustAnchor_GetNameConstraints(
    512        PKIX_TrustAnchor *anchor,
    513        PKIX_PL_CertNameConstraints **pNameConstraints,
    514        void *plContext)
    515 {
    516        PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetNameConstraints");
    517        PKIX_NULLCHECK_TWO(anchor, pNameConstraints);
    518 
    519        PKIX_INCREF(anchor->nameConstraints);
    520 
    521        *pNameConstraints = anchor->nameConstraints;
    522 
    523 cleanup:
    524        PKIX_RETURN(TRUSTANCHOR);
    525 }