tor-browser

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

pkix_pl_oid.c (9071B)


      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_pl_oid.c
      6 *
      7 * OID Object Functions
      8 *
      9 */
     10 
     11 #include "pkix_pl_oid.h"
     12 
     13 /* --Private-OID-Functions---------------------------------------- */
     14 
     15 /*
     16 * FUNCTION: pkix_pl_OID_Comparator
     17 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
     18 */
     19 static PKIX_Error *
     20 pkix_pl_OID_Comparator(
     21        PKIX_PL_Object *firstObject,
     22        PKIX_PL_Object *secondObject,
     23        PKIX_Int32 *pRes,
     24        void *plContext)
     25 {
     26        PKIX_PL_OID *firstOID = NULL;
     27        PKIX_PL_OID *secondOID = NULL;
     28 
     29        PKIX_ENTER(OID, "pkix_pl_OID_Comparator");
     30        PKIX_NULLCHECK_THREE(firstObject, secondObject, pRes);
     31 
     32        PKIX_CHECK(pkix_CheckTypes
     33                    (firstObject, secondObject, PKIX_OID_TYPE, plContext),
     34                    PKIX_ARGUMENTSNOTOIDS);
     35 
     36        firstOID = (PKIX_PL_OID*)firstObject;
     37        secondOID = (PKIX_PL_OID*)secondObject;
     38 
     39        *pRes = (PKIX_Int32)SECITEM_CompareItem(&firstOID->derOid,
     40                                                &secondOID->derOid);
     41 cleanup:
     42        PKIX_RETURN(OID);
     43 }
     44 
     45 /*
     46 * FUNCTION: pkix_pl_OID_Destroy
     47 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
     48 */
     49 static PKIX_Error *
     50 pkix_pl_OID_Destroy(
     51        PKIX_PL_Object *object,
     52        void *plContext)
     53 {
     54        PKIX_PL_OID *oid = NULL;
     55 
     56        PKIX_ENTER(OID, "pkix_pl_OID_Destroy");
     57        PKIX_NULLCHECK_ONE(object);
     58 
     59        PKIX_CHECK(pkix_CheckType(object, PKIX_OID_TYPE, plContext),
     60                    PKIX_OBJECTNOTANOID);
     61        oid = (PKIX_PL_OID*)object;
     62        SECITEM_FreeItem(&oid->derOid, PR_FALSE);
     63 
     64 cleanup:
     65        PKIX_RETURN(OID);
     66 }
     67 
     68 /*
     69 * FUNCTION: pkix_pl_OID_Hashcode
     70 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
     71 */
     72 static PKIX_Error *
     73 pkix_pl_OID_Hashcode(
     74        PKIX_PL_Object *object,
     75        PKIX_UInt32 *pHashcode,
     76        void *plContext)
     77 {
     78        PKIX_PL_OID *oid = NULL;
     79 
     80        PKIX_ENTER(OID, "pkix_pl_OID_HashCode");
     81        PKIX_NULLCHECK_TWO(object, pHashcode);
     82 
     83        PKIX_CHECK(pkix_CheckType(object, PKIX_OID_TYPE, plContext),
     84                    PKIX_OBJECTNOTANOID);
     85 
     86        oid = (PKIX_PL_OID *)object;
     87 
     88        PKIX_CHECK(pkix_hash
     89                    ((unsigned char *)oid->derOid.data,
     90                    oid->derOid.len * sizeof (char),
     91                    pHashcode,
     92                    plContext),
     93                    PKIX_HASHFAILED);
     94 cleanup:
     95 
     96        PKIX_RETURN(OID);
     97 }
     98 
     99 /*
    100 * FUNCTION: pkix_pl_OID_Equals
    101 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
    102 */
    103 static PKIX_Error *
    104 pkix_pl_OID_Equals(
    105        PKIX_PL_Object *first,
    106        PKIX_PL_Object *second,
    107        PKIX_Boolean *pResult,
    108        void *plContext)
    109 {
    110        PKIX_Int32 cmpResult;
    111 
    112        PKIX_ENTER(OID, "pkix_pl_OID_Equals");
    113        PKIX_NULLCHECK_THREE(first, second, pResult);
    114 
    115        PKIX_CHECK(pkix_pl_OID_Comparator
    116                    (first, second, &cmpResult, plContext),
    117                    PKIX_OIDCOMPARATORFAILED);
    118 
    119        *pResult = (cmpResult == 0);
    120 cleanup:
    121 
    122        PKIX_RETURN(OID);
    123 }
    124 
    125 /*
    126 * FUNCTION: pkix_pl_OID_ToString
    127 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
    128 * Use this function only for printing OIDs and not to make any
    129 * critical security decision.
    130 */
    131 static PKIX_Error *
    132 pkix_pl_OID_ToString(
    133        PKIX_PL_Object *object,
    134        PKIX_PL_String **pString,
    135        void *plContext)
    136 {
    137        PKIX_PL_OID *oid = NULL;
    138        char *oidString = NULL;
    139 
    140        PKIX_ENTER(OID, "pkix_pl_OID_toString");
    141        PKIX_NULLCHECK_TWO(object, pString);
    142 
    143        PKIX_CHECK(pkix_CheckType(object, PKIX_OID_TYPE, plContext),
    144                    PKIX_OBJECTNOTANOID);
    145        oid = (PKIX_PL_OID*)object;
    146        oidString = CERT_GetOidString(&oid->derOid);
    147        
    148        PKIX_CHECK(PKIX_PL_String_Create
    149                (PKIX_ESCASCII, oidString , 0, pString, plContext),
    150                PKIX_STRINGCREATEFAILED);
    151 cleanup:
    152        PR_smprintf_free(oidString);
    153        
    154        PKIX_RETURN(OID);
    155 }
    156 
    157 /*
    158 * FUNCTION: pkix_pl_OID_RegisterSelf
    159 * DESCRIPTION:
    160 *  Registers PKIX_OID_TYPE and its related functions with systemClasses[]
    161 * THREAD SAFETY:
    162 *  Not Thread Safe - for performance and complexity reasons
    163 *
    164 *  Since this function is only called by PKIX_PL_Initialize, which should
    165 *  only be called once, it is acceptable that this function is not
    166 *  thread-safe.
    167 */
    168 PKIX_Error *
    169 pkix_pl_OID_RegisterSelf(
    170        void *plContext)
    171 {
    172        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    173        pkix_ClassTable_Entry *entry = &systemClasses[PKIX_OID_TYPE];
    174 
    175        PKIX_ENTER(OID, "pkix_pl_OID_RegisterSelf");
    176 
    177        entry->description = "OID";
    178        entry->typeObjectSize = sizeof(PKIX_PL_OID);
    179        entry->destructor = pkix_pl_OID_Destroy;
    180        entry->equalsFunction = pkix_pl_OID_Equals;
    181        entry->hashcodeFunction = pkix_pl_OID_Hashcode;
    182        entry->toStringFunction = pkix_pl_OID_ToString;
    183        entry->comparator = pkix_pl_OID_Comparator;
    184        entry->duplicateFunction = pkix_duplicateImmutable;
    185 
    186        PKIX_RETURN(OID);
    187 }
    188 
    189 /*
    190 * FUNCTION: pkix_pl_OID_GetCriticalExtensionOIDs
    191 * DESCRIPTION:
    192 *
    193 *  Converts the extensions in "extensions" array that are critical to
    194 *  PKIX_PL_OID and returns the result as a PKIX_List in "pPidList".
    195 *  If there is no critical extension, an empty list is returned.
    196 *
    197 * PARAMETERS
    198 *  "extension"
    199 *      an array of extension pointers. May be NULL.
    200 *  "pOidsList"
    201 *      Address where the list of OIDs is returned. Must be non-NULL.
    202 * THREAD SAFETY:
    203 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    204 * RETURNS:
    205 *  Returns NULL if the function succeeds.
    206 *  Returns a CRL Error if the function fails in a non-fatal way.
    207 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    208 */
    209 PKIX_Error *
    210 pkix_pl_OID_GetCriticalExtensionOIDs(
    211        CERTCertExtension **extensions,
    212        PKIX_List **pOidsList,
    213        void *plContext)
    214 {
    215        PKIX_List *oidsList = NULL;
    216        PKIX_PL_OID *pkixOID = NULL;
    217 
    218        PKIX_ENTER(OID, "pkix_pl_OID_GetCriticalExtensionOIDs");
    219        PKIX_NULLCHECK_ONE(pOidsList);
    220 
    221        PKIX_CHECK(PKIX_List_Create(&oidsList, plContext),
    222                    PKIX_LISTCREATEFAILED);
    223 
    224        if (extensions) {
    225            while (*extensions) {
    226                CERTCertExtension *extension = NULL;
    227                SECItem *critical = NULL;
    228                SECItem *oid = NULL;
    229 
    230                extension = *extensions++;
    231                /* extension is critical ? */
    232                critical = &extension->critical;
    233                if (critical->len == 0 || critical->data[0] == 0) {
    234                    continue;
    235                }
    236                oid = &extension->id;
    237                PKIX_CHECK(
    238                    PKIX_PL_OID_CreateBySECItem(oid, &pkixOID, plContext),
    239                    PKIX_OIDCREATEFAILED);
    240                PKIX_CHECK(
    241                    PKIX_List_AppendItem(oidsList, (PKIX_PL_Object *)pkixOID,
    242                                         plContext),
    243                    PKIX_LISTAPPENDITEMFAILED);
    244                PKIX_DECREF(pkixOID);
    245            }
    246        }
    247 
    248        *pOidsList = oidsList;
    249        oidsList = NULL;
    250        
    251 cleanup:
    252        PKIX_DECREF(oidsList);
    253        PKIX_DECREF(pkixOID);
    254        PKIX_RETURN(OID);
    255 }
    256 
    257 /* --Public-Functions------------------------------------------------------- */
    258 
    259 /*
    260 * FUNCTION: PKIX_PL_OID_CreateBySECItem (see comments in pkix_pl_system.h)
    261 */
    262 PKIX_Error *
    263 PKIX_PL_OID_CreateBySECItem(
    264        SECItem *derOid,
    265        PKIX_PL_OID **pOID,
    266        void *plContext)
    267 {
    268        PKIX_PL_OID *oid = NULL;
    269        SECStatus rv;
    270        
    271        PKIX_ENTER(OID, "PKIX_PL_OID_CreateBySECItem");
    272        PKIX_NULLCHECK_TWO(pOID, derOid);
    273 
    274        PKIX_CHECK(PKIX_PL_Object_Alloc
    275                   (PKIX_OID_TYPE,
    276                    sizeof (PKIX_PL_OID),
    277                    (PKIX_PL_Object **)&oid,
    278                    plContext),
    279                    PKIX_COULDNOTCREATEOBJECT);
    280        rv = SECITEM_CopyItem(NULL, &oid->derOid, derOid);
    281        if (rv != SECSuccess) {
    282            PKIX_ERROR(PKIX_OUTOFMEMORY);
    283        }
    284        *pOID = oid;
    285        oid = NULL;
    286        
    287 cleanup:
    288        PKIX_DECREF(oid);
    289        
    290        PKIX_RETURN(OID);
    291 }
    292 
    293 /*
    294 * FUNCTION: PKIX_PL_OID_Create (see comments in pkix_pl_system.h)
    295 */
    296 PKIX_Error *
    297 PKIX_PL_OID_Create(
    298        SECOidTag idtag,
    299        PKIX_PL_OID **pOID,
    300        void *plContext)
    301 {
    302        SECOidData *oidData = NULL;
    303    
    304        PKIX_ENTER(OID, "PKIX_PL_OID_Create");
    305        PKIX_NULLCHECK_ONE(pOID);
    306 
    307        oidData = SECOID_FindOIDByTag((SECOidTag)idtag);
    308        if (!oidData) {
    309            PKIX_ERROR(PKIX_SECOIDFINDOIDTAGDESCRIPTIONFAILED);
    310        }
    311        
    312        pkixErrorResult = 
    313            PKIX_PL_OID_CreateBySECItem(&oidData->oid, pOID, plContext);
    314 cleanup:
    315        PKIX_RETURN(OID);
    316 }