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 }