| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | 4 |
| 5 #include "plarena.h" | 5 #include "plarena.h" |
| 6 #include "seccomon.h" | 6 #include "seccomon.h" |
| 7 #include "secitem.h" | 7 #include "secitem.h" |
| 8 #include "secoidt.h" | 8 #include "secoidt.h" |
| 9 #include "secasn1.h" | 9 #include "secasn1.h" |
| 10 #include "secder.h" | 10 #include "secder.h" |
| 11 #include "certt.h" | 11 #include "certt.h" |
| 12 #include "cert.h" | 12 #include "cert.h" |
| 13 #include "certi.h" | 13 #include "certi.h" |
| 14 #include "xconst.h" | 14 #include "xconst.h" |
| 15 #include "secerr.h" | 15 #include "secerr.h" |
| 16 #include "secoid.h" | 16 #include "secoid.h" |
| 17 #include "prprf.h" | 17 #include "prprf.h" |
| 18 #include "genname.h" | 18 #include "genname.h" |
| 19 | 19 |
| 20 SEC_ASN1_MKSUB(SEC_AnyTemplate) | 20 SEC_ASN1_MKSUB(SEC_AnyTemplate) |
| 21 SEC_ASN1_MKSUB(SEC_IntegerTemplate) | 21 SEC_ASN1_MKSUB(SEC_IntegerTemplate) |
| 22 SEC_ASN1_MKSUB(SEC_IA5StringTemplate) | 22 SEC_ASN1_MKSUB(SEC_IA5StringTemplate) |
| 23 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) | 23 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) |
| 24 SEC_ASN1_MKSUB(SEC_OctetStringTemplate) | 24 SEC_ASN1_MKSUB(SEC_OctetStringTemplate) |
| 25 | 25 |
| 26 static const SEC_ASN1Template CERTNameConstraintTemplate[] = { | 26 static const SEC_ASN1Template CERTNameConstraintTemplate[] = { |
| 27 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraint) }, | 27 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraint) }, |
| 28 { SEC_ASN1_ANY, offsetof(CERTNameConstraint, DERName) }, | 28 { SEC_ASN1_ANY, offsetof(CERTNameConstraint, DERName) }, |
| 29 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, | 29 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, |
| 30 offsetof(CERTNameConstraint, min), | 30 offsetof(CERTNameConstraint, min), SEC_ASN1_SUB(SEC_IntegerTemplate) }, |
| 31 SEC_ASN1_SUB(SEC_IntegerTemplate) }, | 31 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, |
| 32 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, | 32 offsetof(CERTNameConstraint, max), SEC_ASN1_SUB(SEC_IntegerTemplate) }, |
| 33 offsetof(CERTNameConstraint, max), | 33 { 0 } |
| 34 SEC_ASN1_SUB(SEC_IntegerTemplate) }, | |
| 35 { 0, } | |
| 36 }; | 34 }; |
| 37 | 35 |
| 38 const SEC_ASN1Template CERT_NameConstraintSubtreeSubTemplate[] = { | 36 const SEC_ASN1Template CERT_NameConstraintSubtreeSubTemplate[] = { |
| 39 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) } | 37 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) } |
| 40 }; | 38 }; |
| 41 | 39 |
| 42 static const SEC_ASN1Template CERTNameConstraintsTemplate[] = { | 40 static const SEC_ASN1Template CERTNameConstraintsTemplate[] = { |
| 43 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraints) }, | 41 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraints) }, |
| 44 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, | 42 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, |
| 45 offsetof(CERTNameConstraints, DERPermited), | 43 offsetof(CERTNameConstraints, DERPermited), |
| 46 » CERT_NameConstraintSubtreeSubTemplate}, | 44 CERT_NameConstraintSubtreeSubTemplate }, |
| 47 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, | 45 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, |
| 48 offsetof(CERTNameConstraints, DERExcluded), | 46 offsetof(CERTNameConstraints, DERExcluded), |
| 49 » CERT_NameConstraintSubtreeSubTemplate}, | 47 CERT_NameConstraintSubtreeSubTemplate }, |
| 50 { 0, } | 48 { 0 } |
| 51 }; | 49 }; |
| 52 | 50 |
| 53 | |
| 54 static const SEC_ASN1Template CERTOthNameTemplate[] = { | 51 static const SEC_ASN1Template CERTOthNameTemplate[] = { |
| 55 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(OtherName) }, | 52 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(OtherName) }, |
| 56 { SEC_ASN1_OBJECT_ID, | 53 { SEC_ASN1_OBJECT_ID, offsetof(OtherName, oid) }, |
| 57 » offsetof(OtherName, oid) }, | |
| 58 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | | 54 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | |
| 59 SEC_ASN1_XTRN | 0, offsetof(OtherName, name), | 55 SEC_ASN1_XTRN | 0, |
| 60 SEC_ASN1_SUB(SEC_AnyTemplate) }, | 56 offsetof(OtherName, name), SEC_ASN1_SUB(SEC_AnyTemplate) }, |
| 61 { 0, } | 57 { 0 } |
| 62 }; | 58 }; |
| 63 | 59 |
| 64 static const SEC_ASN1Template CERTOtherNameTemplate[] = { | 60 static const SEC_ASN1Template CERTOtherNameTemplate[] = { |
| 65 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0 , | 61 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0, |
| 66 offsetof(CERTGeneralName, name.OthName), CERTOthNameTemplate, | 62 offsetof(CERTGeneralName, name.OthName), CERTOthNameTemplate, |
| 67 sizeof(CERTGeneralName) } | 63 sizeof(CERTGeneralName) } |
| 68 }; | 64 }; |
| 69 | 65 |
| 70 static const SEC_ASN1Template CERT_RFC822NameTemplate[] = { | 66 static const SEC_ASN1Template CERT_RFC822NameTemplate[] = { |
| 71 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1 , | 67 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, |
| 72 offsetof(CERTGeneralName, name.other), | 68 offsetof(CERTGeneralName, name.other), |
| 73 SEC_ASN1_SUB(SEC_IA5StringTemplate), | 69 SEC_ASN1_SUB(SEC_IA5StringTemplate), sizeof(CERTGeneralName) } |
| 74 sizeof (CERTGeneralName)} | |
| 75 }; | 70 }; |
| 76 | 71 |
| 77 static const SEC_ASN1Template CERT_DNSNameTemplate[] = { | 72 static const SEC_ASN1Template CERT_DNSNameTemplate[] = { |
| 78 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2 , | 73 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, |
| 79 offsetof(CERTGeneralName, name.other), | 74 offsetof(CERTGeneralName, name.other), |
| 80 SEC_ASN1_SUB(SEC_IA5StringTemplate), | 75 SEC_ASN1_SUB(SEC_IA5StringTemplate), sizeof(CERTGeneralName) } |
| 81 sizeof (CERTGeneralName)} | |
| 82 }; | 76 }; |
| 83 | 77 |
| 84 static const SEC_ASN1Template CERT_X400AddressTemplate[] = { | 78 static const SEC_ASN1Template CERT_X400AddressTemplate[] = { |
| 85 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 3, | 79 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 3, |
| 86 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate), | 80 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate), |
| 87 sizeof (CERTGeneralName)} | 81 sizeof(CERTGeneralName) } |
| 88 }; | 82 }; |
| 89 | 83 |
| 90 static const SEC_ASN1Template CERT_DirectoryNameTemplate[] = { | 84 static const SEC_ASN1Template CERT_DirectoryNameTemplate[] = { |
| 91 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | | 85 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | |
| 92 SEC_ASN1_XTRN | 4, offsetof(CERTGeneralName, derDirectoryName), | 86 SEC_ASN1_XTRN | 4, |
| 93 SEC_ASN1_SUB(SEC_AnyTemplate), sizeof (CERTGeneralName)} | 87 offsetof(CERTGeneralName, derDirectoryName), |
| 88 SEC_ASN1_SUB(SEC_AnyTemplate), sizeof(CERTGeneralName) } |
| 94 }; | 89 }; |
| 95 | 90 |
| 96 | |
| 97 static const SEC_ASN1Template CERT_EDIPartyNameTemplate[] = { | 91 static const SEC_ASN1Template CERT_EDIPartyNameTemplate[] = { |
| 98 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 5, | 92 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 5, |
| 99 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate), | 93 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate), |
| 100 sizeof (CERTGeneralName)} | 94 sizeof(CERTGeneralName) } |
| 101 }; | 95 }; |
| 102 | 96 |
| 103 static const SEC_ASN1Template CERT_URITemplate[] = { | 97 static const SEC_ASN1Template CERT_URITemplate[] = { |
| 104 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 6 , | 98 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 6, |
| 105 offsetof(CERTGeneralName, name.other), | 99 offsetof(CERTGeneralName, name.other), |
| 106 SEC_ASN1_SUB(SEC_IA5StringTemplate), | 100 SEC_ASN1_SUB(SEC_IA5StringTemplate), sizeof(CERTGeneralName) } |
| 107 sizeof (CERTGeneralName)} | |
| 108 }; | 101 }; |
| 109 | 102 |
| 110 static const SEC_ASN1Template CERT_IPAddressTemplate[] = { | 103 static const SEC_ASN1Template CERT_IPAddressTemplate[] = { |
| 111 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 7 , | 104 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 7, |
| 112 offsetof(CERTGeneralName, name.other), | 105 offsetof(CERTGeneralName, name.other), |
| 113 SEC_ASN1_SUB(SEC_OctetStringTemplate), | 106 SEC_ASN1_SUB(SEC_OctetStringTemplate), sizeof(CERTGeneralName) } |
| 114 sizeof (CERTGeneralName)} | |
| 115 }; | 107 }; |
| 116 | 108 |
| 117 static const SEC_ASN1Template CERT_RegisteredIDTemplate[] = { | 109 static const SEC_ASN1Template CERT_RegisteredIDTemplate[] = { |
| 118 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 8 , | 110 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 8, |
| 119 offsetof(CERTGeneralName, name.other), | 111 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_ObjectIDTemplate), |
| 120 SEC_ASN1_SUB(SEC_ObjectIDTemplate), | 112 sizeof(CERTGeneralName) } |
| 121 sizeof (CERTGeneralName)} | |
| 122 }; | 113 }; |
| 123 | 114 |
| 124 | |
| 125 const SEC_ASN1Template CERT_GeneralNamesTemplate[] = { | 115 const SEC_ASN1Template CERT_GeneralNamesTemplate[] = { |
| 126 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN , 0, SEC_ASN1_SUB(SEC_AnyTemplate) } | 116 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) } |
| 127 }; | 117 }; |
| 128 | 118 |
| 129 | |
| 130 static struct { | 119 static struct { |
| 131 CERTGeneralNameType type; | 120 CERTGeneralNameType type; |
| 132 char *name; | 121 char *name; |
| 133 } typesArray[] = { | 122 } typesArray[] = { { certOtherName, "other" }, |
| 134 { certOtherName, "other" }, | 123 { certRFC822Name, "email" }, |
| 135 { certRFC822Name, "email" }, | 124 { certRFC822Name, "rfc822" }, |
| 136 { certRFC822Name, "rfc822" }, | 125 { certDNSName, "dns" }, |
| 137 { certDNSName, "dns" }, | 126 { certX400Address, "x400" }, |
| 138 { certX400Address, "x400" }, | 127 { certX400Address, "x400addr" }, |
| 139 { certX400Address, "x400addr" }, | 128 { certDirectoryName, "directory" }, |
| 140 { certDirectoryName, "directory" }, | 129 { certDirectoryName, "dn" }, |
| 141 { certDirectoryName, "dn" }, | 130 { certEDIPartyName, "edi" }, |
| 142 { certEDIPartyName, "edi" }, | 131 { certEDIPartyName, "ediparty" }, |
| 143 { certEDIPartyName, "ediparty" }, | 132 { certURI, "uri" }, |
| 144 { certURI, "uri" }, | 133 { certIPAddress, "ip" }, |
| 145 { certIPAddress, "ip" }, | 134 { certIPAddress, "ipaddr" }, |
| 146 { certIPAddress, "ipaddr" }, | 135 { certRegisterID, "registerid" } }; |
| 147 { certRegisterID, "registerid" } | |
| 148 }; | |
| 149 | 136 |
| 150 CERTGeneralNameType | 137 CERTGeneralNameType |
| 151 CERT_GetGeneralNameTypeFromString(const char *string) | 138 CERT_GetGeneralNameTypeFromString(const char *string) |
| 152 { | 139 { |
| 153 int types_count = sizeof(typesArray)/sizeof(typesArray[0]); | 140 int types_count = sizeof(typesArray) / sizeof(typesArray[0]); |
| 154 int i; | 141 int i; |
| 155 | 142 |
| 156 for (i=0; i < types_count; i++) { | 143 for (i = 0; i < types_count; i++) { |
| 157 if (PORT_Strcasecmp(string, typesArray[i].name) == 0) { | 144 if (PORT_Strcasecmp(string, typesArray[i].name) == 0) { |
| 158 return typesArray[i].type; | 145 return typesArray[i].type; |
| 159 } | 146 } |
| 160 } | 147 } |
| 161 return 0; | 148 return 0; |
| 162 } | 149 } |
| 163 | 150 |
| 164 CERTGeneralName * | 151 CERTGeneralName * |
| 165 CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type) | 152 CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type) |
| 166 { | 153 { |
| 167 CERTGeneralName *name = arena | 154 CERTGeneralName *name = arena ? PORT_ArenaZNew(arena, CERTGeneralName) |
| 168 ? PORT_ArenaZNew(arena, CERTGeneralName) | 155 : PORT_ZNew(CERTGeneralName); |
| 169 » : PORT_ZNew(CERTGeneralName); | |
| 170 if (name) { | 156 if (name) { |
| 171 » name->type = type; | 157 name->type = type; |
| 172 » name->l.prev = name->l.next = &name->l; | 158 name->l.prev = name->l.next = &name->l; |
| 173 } | 159 } |
| 174 return name; | 160 return name; |
| 175 } | 161 } |
| 176 | 162 |
| 177 /* Copy content of one General Name to another. | 163 /* Copy content of one General Name to another. |
| 178 ** Caller has allocated destination general name. | 164 ** Caller has allocated destination general name. |
| 179 ** This function does not change the destinate's GeneralName's list linkage. | 165 ** This function does not change the destinate's GeneralName's list linkage. |
| 180 */ | 166 */ |
| 181 SECStatus | 167 SECStatus |
| 182 cert_CopyOneGeneralName(PLArenaPool *arena, | 168 cert_CopyOneGeneralName(PLArenaPool *arena, CERTGeneralName *dest, |
| 183 » » CERTGeneralName *dest, | 169 CERTGeneralName *src) |
| 184 » » CERTGeneralName *src) | |
| 185 { | 170 { |
| 186 SECStatus rv; | 171 SECStatus rv; |
| 187 void *mark = NULL; | 172 void *mark = NULL; |
| 188 | 173 |
| 189 PORT_Assert(dest != NULL); | 174 PORT_Assert(dest != NULL); |
| 190 dest->type = src->type; | 175 dest->type = src->type; |
| 191 | 176 |
| 192 mark = PORT_ArenaMark(arena); | 177 mark = PORT_ArenaMark(arena); |
| 193 | 178 |
| 194 switch (src->type) { | 179 switch (src->type) { |
| 195 case certDirectoryName: | 180 case certDirectoryName: |
| 196 » rv = SECITEM_CopyItem(arena, &dest->derDirectoryName, | 181 rv = SECITEM_CopyItem(arena, &dest->derDirectoryName, |
| 197 » » » » &src->derDirectoryName); | 182 &src->derDirectoryName); |
| 198 » if (rv == SECSuccess) | 183 if (rv == SECSuccess) |
| 199 » rv = CERT_CopyName(arena, &dest->name.directoryName, | 184 rv = CERT_CopyName(arena, &dest->name.directoryName, |
| 200 » » » » &src->name.directoryName); | 185 &src->name.directoryName); |
| 201 » break; | 186 break; |
| 202 | 187 |
| 203 case certOtherName: | 188 case certOtherName: |
| 204 » rv = SECITEM_CopyItem(arena, &dest->name.OthName.name, | 189 rv = SECITEM_CopyItem(arena, &dest->name.OthName.name, |
| 205 » » » » &src->name.OthName.name); | 190 &src->name.OthName.name); |
| 206 » if (rv == SECSuccess) | 191 if (rv == SECSuccess) |
| 207 » rv = SECITEM_CopyItem(arena, &dest->name.OthName.oid, | 192 rv = SECITEM_CopyItem(arena, &dest->name.OthName.oid, |
| 208 » » » » » &src->name.OthName.oid); | 193 &src->name.OthName.oid); |
| 209 » break; | 194 break; |
| 210 | 195 |
| 211 default: | 196 default: |
| 212 » rv = SECITEM_CopyItem(arena, &dest->name.other, | 197 rv = SECITEM_CopyItem(arena, &dest->name.other, &src->name.other); |
| 213 » » » » &src->name.other); | 198 break; |
| 214 » break; | |
| 215 | |
| 216 } | 199 } |
| 217 if (rv != SECSuccess) { | 200 if (rv != SECSuccess) { |
| 218 PORT_ArenaRelease(arena, mark); | 201 PORT_ArenaRelease(arena, mark); |
| 219 } else { | 202 } else { |
| 220 PORT_ArenaUnmark(arena, mark); | 203 PORT_ArenaUnmark(arena, mark); |
| 221 } | 204 } |
| 222 return rv; | 205 return rv; |
| 223 } | 206 } |
| 224 | 207 |
| 225 | |
| 226 void | 208 void |
| 227 CERT_DestroyGeneralNameList(CERTGeneralNameList *list) | 209 CERT_DestroyGeneralNameList(CERTGeneralNameList *list) |
| 228 { | 210 { |
| 229 PZLock *lock; | 211 PZLock *lock; |
| 230 | 212 |
| 231 if (list != NULL) { | 213 if (list != NULL) { |
| 232 » lock = list->lock; | 214 lock = list->lock; |
| 233 » PZ_Lock(lock); | 215 PZ_Lock(lock); |
| 234 » if (--list->refCount <= 0 && list->arena != NULL) { | 216 if (--list->refCount <= 0 && list->arena != NULL) { |
| 235 » PORT_FreeArena(list->arena, PR_FALSE); | 217 PORT_FreeArena(list->arena, PR_FALSE); |
| 236 » PZ_Unlock(lock); | 218 PZ_Unlock(lock); |
| 237 » PZ_DestroyLock(lock); | 219 PZ_DestroyLock(lock); |
| 238 » } else { | 220 } else { |
| 239 » PZ_Unlock(lock); | 221 PZ_Unlock(lock); |
| 240 » } | 222 } |
| 241 } | 223 } |
| 242 return; | 224 return; |
| 243 } | 225 } |
| 244 | 226 |
| 245 CERTGeneralNameList * | 227 CERTGeneralNameList * |
| 246 CERT_CreateGeneralNameList(CERTGeneralName *name) { | 228 CERT_CreateGeneralNameList(CERTGeneralName *name) |
| 229 { |
| 247 PLArenaPool *arena; | 230 PLArenaPool *arena; |
| 248 CERTGeneralNameList *list = NULL; | 231 CERTGeneralNameList *list = NULL; |
| 249 | 232 |
| 250 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 233 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 251 if (arena == NULL) { | 234 if (arena == NULL) { |
| 252 » goto done; | 235 goto done; |
| 253 } | 236 } |
| 254 list = PORT_ArenaZNew(arena, CERTGeneralNameList); | 237 list = PORT_ArenaZNew(arena, CERTGeneralNameList); |
| 255 if (!list) | 238 if (!list) |
| 256 » goto loser; | 239 goto loser; |
| 257 if (name != NULL) { | 240 if (name != NULL) { |
| 258 » SECStatus rv; | 241 SECStatus rv; |
| 259 » list->name = CERT_NewGeneralName(arena, (CERTGeneralNameType)0); | 242 list->name = CERT_NewGeneralName(arena, (CERTGeneralNameType)0); |
| 260 » if (!list->name) | 243 if (!list->name) |
| 261 » goto loser; | 244 goto loser; |
| 262 » rv = CERT_CopyGeneralName(arena, list->name, name); | 245 rv = CERT_CopyGeneralName(arena, list->name, name); |
| 263 » if (rv != SECSuccess) | 246 if (rv != SECSuccess) |
| 264 » goto loser; | 247 goto loser; |
| 265 } | 248 } |
| 266 list->lock = PZ_NewLock(nssILockList); | 249 list->lock = PZ_NewLock(nssILockList); |
| 267 if (!list->lock) | 250 if (!list->lock) |
| 268 » goto loser; | 251 goto loser; |
| 269 list->arena = arena; | 252 list->arena = arena; |
| 270 list->refCount = 1; | 253 list->refCount = 1; |
| 271 done: | 254 done: |
| 272 return list; | 255 return list; |
| 273 | 256 |
| 274 loser: | 257 loser: |
| 275 PORT_FreeArena(arena, PR_FALSE); | 258 PORT_FreeArena(arena, PR_FALSE); |
| 276 return NULL; | 259 return NULL; |
| 277 } | 260 } |
| 278 | 261 |
| 279 CERTGeneralName * | 262 CERTGeneralName * |
| 280 CERT_GetNextGeneralName(CERTGeneralName *current) | 263 CERT_GetNextGeneralName(CERTGeneralName *current) |
| 281 { | 264 { |
| 282 PRCList *next; | 265 PRCList *next; |
| 283 | 266 |
| 284 next = current->l.next; | 267 next = current->l.next; |
| 285 return (CERTGeneralName *) (((char *) next) - offsetof(CERTGeneralName, l)); | 268 return (CERTGeneralName *)(((char *)next) - offsetof(CERTGeneralName, l)); |
| 286 } | 269 } |
| 287 | 270 |
| 288 CERTGeneralName * | 271 CERTGeneralName * |
| 289 CERT_GetPrevGeneralName(CERTGeneralName *current) | 272 CERT_GetPrevGeneralName(CERTGeneralName *current) |
| 290 { | 273 { |
| 291 PRCList *prev; | 274 PRCList *prev; |
| 292 prev = current->l.prev; | 275 prev = current->l.prev; |
| 293 return (CERTGeneralName *) (((char *) prev) - offsetof(CERTGeneralName, l)); | 276 return (CERTGeneralName *)(((char *)prev) - offsetof(CERTGeneralName, l)); |
| 294 } | 277 } |
| 295 | 278 |
| 296 CERTNameConstraint * | 279 CERTNameConstraint * |
| 297 CERT_GetNextNameConstraint(CERTNameConstraint *current) | 280 CERT_GetNextNameConstraint(CERTNameConstraint *current) |
| 298 { | 281 { |
| 299 PRCList *next; | 282 PRCList *next; |
| 300 | 283 |
| 301 next = current->l.next; | 284 next = current->l.next; |
| 302 return (CERTNameConstraint *) (((char *) next) - offsetof(CERTNameConstraint
, l)); | 285 return (CERTNameConstraint *)(((char *)next) - |
| 286 offsetof(CERTNameConstraint, l)); |
| 303 } | 287 } |
| 304 | 288 |
| 305 CERTNameConstraint * | 289 CERTNameConstraint * |
| 306 CERT_GetPrevNameConstraint(CERTNameConstraint *current) | 290 CERT_GetPrevNameConstraint(CERTNameConstraint *current) |
| 307 { | 291 { |
| 308 PRCList *prev; | 292 PRCList *prev; |
| 309 prev = current->l.prev; | 293 prev = current->l.prev; |
| 310 return (CERTNameConstraint *) (((char *) prev) - offsetof(CERTNameConstraint
, l)); | 294 return (CERTNameConstraint *)(((char *)prev) - |
| 295 offsetof(CERTNameConstraint, l)); |
| 311 } | 296 } |
| 312 | 297 |
| 313 SECItem * | 298 SECItem * |
| 314 CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PLArenaPool *are
na) | 299 CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, |
| 300 PLArenaPool *arena) |
| 315 { | 301 { |
| 316 | 302 |
| 317 const SEC_ASN1Template * template; | 303 const SEC_ASN1Template *template; |
| 318 | 304 |
| 319 PORT_Assert(arena); | 305 PORT_Assert(arena); |
| 320 if (arena == NULL) { | 306 if (arena == NULL) { |
| 321 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 307 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 322 » return NULL; | 308 return NULL; |
| 323 } | 309 } |
| 324 /* TODO: mark arena */ | 310 /* TODO: mark arena */ |
| 325 if (dest == NULL) { | 311 if (dest == NULL) { |
| 326 » dest = PORT_ArenaZNew(arena, SECItem); | 312 dest = PORT_ArenaZNew(arena, SECItem); |
| 327 » if (!dest) | 313 if (!dest) |
| 328 » goto loser; | 314 goto loser; |
| 329 } | 315 } |
| 330 if (genName->type == certDirectoryName) { | 316 if (genName->type == certDirectoryName) { |
| 331 » if (genName->derDirectoryName.data == NULL) { | 317 if (genName->derDirectoryName.data == NULL) { |
| 332 » /* The field hasn't been encoded yet. */ | 318 /* The field hasn't been encoded yet. */ |
| 333 SECItem * pre_dest = | 319 SECItem *pre_dest = SEC_ASN1EncodeItem( |
| 334 SEC_ASN1EncodeItem (arena, &(genName->derDirectoryName), | 320 arena, &(genName->derDirectoryName), |
| 335 &(genName->name.directoryName), | 321 &(genName->name.directoryName), CERT_NameTemplate); |
| 336 CERT_NameTemplate); | |
| 337 if (!pre_dest) | 322 if (!pre_dest) |
| 338 goto loser; | 323 goto loser; |
| 339 » } | 324 } |
| 340 » if (genName->derDirectoryName.data == NULL) { | 325 if (genName->derDirectoryName.data == NULL) { |
| 341 » goto loser; | 326 goto loser; |
| 342 » } | 327 } |
| 343 } | 328 } |
| 344 switch (genName->type) { | 329 switch (genName->type) { |
| 345 case certURI: template = CERT_URITemplate; break; | 330 case certURI: |
| 346 case certRFC822Name: template = CERT_RFC822NameTemplate; break; | 331 template = CERT_URITemplate; |
| 347 case certDNSName: template = CERT_DNSNameTemplate; break; | 332 break; |
| 348 case certIPAddress: template = CERT_IPAddressTemplate; break; | 333 case certRFC822Name: |
| 349 case certOtherName: template = CERTOtherNameTemplate; break; | 334 template = CERT_RFC822NameTemplate; |
| 350 case certRegisterID: template = CERT_RegisteredIDTemplate; break; | 335 break; |
| 351 /* for this type, we expect the value is already encoded */ | 336 case certDNSName: |
| 352 case certEDIPartyName: template = CERT_EDIPartyNameTemplate; break; | 337 template = CERT_DNSNameTemplate; |
| 353 » /* for this type, we expect the value is already encoded */ | 338 break; |
| 354 case certX400Address: template = CERT_X400AddressTemplate; break; | 339 case certIPAddress: |
| 355 case certDirectoryName: template = CERT_DirectoryNameTemplate; break; | 340 template = CERT_IPAddressTemplate; |
| 356 default: | 341 break; |
| 357 » PORT_Assert(0); goto loser; | 342 case certOtherName: |
| 343 template = CERTOtherNameTemplate; |
| 344 break; |
| 345 case certRegisterID: |
| 346 template = CERT_RegisteredIDTemplate; |
| 347 break; |
| 348 /* for this type, we expect the value is already encoded */ |
| 349 case certEDIPartyName: |
| 350 template = CERT_EDIPartyNameTemplate; |
| 351 break; |
| 352 /* for this type, we expect the value is already encoded */ |
| 353 case certX400Address: |
| 354 template = CERT_X400AddressTemplate; |
| 355 break; |
| 356 case certDirectoryName: |
| 357 template = CERT_DirectoryNameTemplate; |
| 358 break; |
| 359 default: |
| 360 PORT_Assert(0); |
| 361 goto loser; |
| 358 } | 362 } |
| 359 dest = SEC_ASN1EncodeItem(arena, dest, genName, template); | 363 dest = SEC_ASN1EncodeItem(arena, dest, genName, template); |
| 360 if (!dest) { | 364 if (!dest) { |
| 361 » goto loser; | 365 goto loser; |
| 362 } | 366 } |
| 363 /* TODO: unmark arena */ | 367 /* TODO: unmark arena */ |
| 364 return dest; | 368 return dest; |
| 365 loser: | 369 loser: |
| 366 /* TODO: release arena back to mark */ | 370 /* TODO: release arena back to mark */ |
| 367 return NULL; | 371 return NULL; |
| 368 } | 372 } |
| 369 | 373 |
| 370 SECItem ** | 374 SECItem ** |
| 371 cert_EncodeGeneralNames(PLArenaPool *arena, CERTGeneralName *names) | 375 cert_EncodeGeneralNames(PLArenaPool *arena, CERTGeneralName *names) |
| 372 { | 376 { |
| 373 CERTGeneralName *current_name; | 377 CERTGeneralName *current_name; |
| 374 SECItem **items = NULL; | 378 SECItem **items = NULL; |
| 375 int count = 0; | 379 int count = 0; |
| 376 int i; | 380 int i; |
| 377 PRCList *head; | 381 PRCList *head; |
| 378 | 382 |
| 379 PORT_Assert(arena); | 383 PORT_Assert(arena); |
| 380 /* TODO: mark arena */ | 384 /* TODO: mark arena */ |
| 381 current_name = names; | 385 current_name = names; |
| 382 if (names != NULL) { | 386 if (names != NULL) { |
| 383 » count = 1; | 387 count = 1; |
| 384 } | 388 } |
| 385 head = &(names->l); | 389 head = &(names->l); |
| 386 while (current_name->l.next != head) { | 390 while (current_name->l.next != head) { |
| 387 » current_name = CERT_GetNextGeneralName(current_name); | 391 current_name = CERT_GetNextGeneralName(current_name); |
| 388 » ++count; | 392 ++count; |
| 389 } | 393 } |
| 390 current_name = CERT_GetNextGeneralName(current_name); | 394 current_name = CERT_GetNextGeneralName(current_name); |
| 391 items = PORT_ArenaNewArray(arena, SECItem *, count + 1); | 395 items = PORT_ArenaNewArray(arena, SECItem *, count + 1); |
| 392 if (items == NULL) { | 396 if (items == NULL) { |
| 393 » goto loser; | 397 goto loser; |
| 394 } | 398 } |
| 395 for (i = 0; i < count; i++) { | 399 for (i = 0; i < count; i++) { |
| 396 » items[i] = CERT_EncodeGeneralName(current_name, (SECItem *)NULL, arena); | 400 items[i] = CERT_EncodeGeneralName(current_name, (SECItem *)NULL, arena); |
| 397 » if (items[i] == NULL) { | 401 if (items[i] == NULL) { |
| 398 » goto loser; | 402 goto loser; |
| 399 » } | 403 } |
| 400 » current_name = CERT_GetNextGeneralName(current_name); | 404 current_name = CERT_GetNextGeneralName(current_name); |
| 401 } | 405 } |
| 402 items[i] = NULL; | 406 items[i] = NULL; |
| 403 /* TODO: unmark arena */ | 407 /* TODO: unmark arena */ |
| 404 return items; | 408 return items; |
| 405 loser: | 409 loser: |
| 406 /* TODO: release arena to mark */ | 410 /* TODO: release arena to mark */ |
| 407 return NULL; | 411 return NULL; |
| 408 } | 412 } |
| 409 | 413 |
| 410 CERTGeneralName * | 414 CERTGeneralName * |
| 411 CERT_DecodeGeneralName(PLArenaPool *reqArena, | 415 CERT_DecodeGeneralName(PLArenaPool *reqArena, SECItem *encodedName, |
| 412 » » SECItem *encodedName, | 416 CERTGeneralName *genName) |
| 413 » » CERTGeneralName *genName) | |
| 414 { | 417 { |
| 415 const SEC_ASN1Template * template; | 418 const SEC_ASN1Template *template; |
| 416 CERTGeneralNameType genNameType; | 419 CERTGeneralNameType genNameType; |
| 417 SECStatus rv = SECSuccess; | 420 SECStatus rv = SECSuccess; |
| 418 SECItem* newEncodedName; | 421 SECItem *newEncodedName; |
| 419 | 422 |
| 420 if (!reqArena) { | 423 if (!reqArena) { |
| 421 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 424 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 422 return NULL; | 425 return NULL; |
| 423 } | 426 } |
| 424 /* make a copy for decoding so the data decoded with QuickDER doesn't | 427 /* make a copy for decoding so the data decoded with QuickDER doesn't |
| 425 point to temporary memory */ | 428 point to temporary memory */ |
| 426 newEncodedName = SECITEM_ArenaDupItem(reqArena, encodedName); | 429 newEncodedName = SECITEM_ArenaDupItem(reqArena, encodedName); |
| 427 if (!newEncodedName) { | 430 if (!newEncodedName) { |
| 428 return NULL; | 431 return NULL; |
| 429 } | 432 } |
| 430 /* TODO: mark arena */ | 433 /* TODO: mark arena */ |
| 431 genNameType = (CERTGeneralNameType)((*(newEncodedName->data) & 0x0f) + 1); | 434 genNameType = (CERTGeneralNameType)((*(newEncodedName->data) & 0x0f) + 1); |
| 432 if (genName == NULL) { | 435 if (genName == NULL) { |
| 433 » genName = CERT_NewGeneralName(reqArena, genNameType); | 436 genName = CERT_NewGeneralName(reqArena, genNameType); |
| 434 » if (!genName) | 437 if (!genName) |
| 435 » goto loser; | 438 goto loser; |
| 436 } else { | 439 } else { |
| 437 » genName->type = genNameType; | 440 genName->type = genNameType; |
| 438 » genName->l.prev = genName->l.next = &genName->l; | 441 genName->l.prev = genName->l.next = &genName->l; |
| 439 } | 442 } |
| 440 | 443 |
| 441 switch (genNameType) { | 444 switch (genNameType) { |
| 442 case certURI: » » template = CERT_URITemplate; break; | 445 case certURI: |
| 443 case certRFC822Name: » template = CERT_RFC822NameTemplate; break; | 446 template = CERT_URITemplate; |
| 444 case certDNSName: » » template = CERT_DNSNameTemplate; break; | 447 break; |
| 445 case certIPAddress: » template = CERT_IPAddressTemplate; break; | 448 case certRFC822Name: |
| 446 case certOtherName: » template = CERTOtherNameTemplate; break; | 449 template = CERT_RFC822NameTemplate; |
| 447 case certRegisterID: » template = CERT_RegisteredIDTemplate; break; | 450 break; |
| 448 case certEDIPartyName: » template = CERT_EDIPartyNameTemplate; break; | 451 case certDNSName: |
| 449 case certX400Address: » template = CERT_X400AddressTemplate; break; | 452 template = CERT_DNSNameTemplate; |
| 450 case certDirectoryName: » template = CERT_DirectoryNameTemplate; break; | 453 break; |
| 451 default: | 454 case certIPAddress: |
| 452 goto loser; | 455 template = CERT_IPAddressTemplate; |
| 456 break; |
| 457 case certOtherName: |
| 458 template = CERTOtherNameTemplate; |
| 459 break; |
| 460 case certRegisterID: |
| 461 template = CERT_RegisteredIDTemplate; |
| 462 break; |
| 463 case certEDIPartyName: |
| 464 template = CERT_EDIPartyNameTemplate; |
| 465 break; |
| 466 case certX400Address: |
| 467 template = CERT_X400AddressTemplate; |
| 468 break; |
| 469 case certDirectoryName: |
| 470 template = CERT_DirectoryNameTemplate; |
| 471 break; |
| 472 default: |
| 473 goto loser; |
| 453 } | 474 } |
| 454 rv = SEC_QuickDERDecodeItem(reqArena, genName, template, newEncodedName); | 475 rv = SEC_QuickDERDecodeItem(reqArena, genName, template, newEncodedName); |
| 455 if (rv != SECSuccess) | 476 if (rv != SECSuccess) |
| 456 » goto loser; | 477 goto loser; |
| 457 if (genNameType == certDirectoryName) { | 478 if (genNameType == certDirectoryName) { |
| 458 » rv = SEC_QuickDERDecodeItem(reqArena, &(genName->name.directoryName), | 479 rv = SEC_QuickDERDecodeItem(reqArena, &(genName->name.directoryName), |
| 459 » » » » CERT_NameTemplate, | 480 CERT_NameTemplate, |
| 460 » » » » &(genName->derDirectoryName)); | 481 &(genName->derDirectoryName)); |
| 461 if (rv != SECSuccess) | 482 if (rv != SECSuccess) |
| 462 » goto loser; | 483 goto loser; |
| 463 } | 484 } |
| 464 | 485 |
| 465 /* TODO: unmark arena */ | 486 /* TODO: unmark arena */ |
| 466 return genName; | 487 return genName; |
| 467 loser: | 488 loser: |
| 468 /* TODO: release arena to mark */ | 489 /* TODO: release arena to mark */ |
| 469 return NULL; | 490 return NULL; |
| 470 } | 491 } |
| 471 | 492 |
| 472 CERTGeneralName * | 493 CERTGeneralName * |
| 473 cert_DecodeGeneralNames (PLArenaPool *arena, | 494 cert_DecodeGeneralNames(PLArenaPool *arena, SECItem **encodedGenName) |
| 474 » » » SECItem **encodedGenName) | |
| 475 { | 495 { |
| 476 PRCList *head = NULL; | 496 PRCList *head = NULL; |
| 477 PRCList *tail = NULL; | 497 PRCList *tail = NULL; |
| 478 CERTGeneralName *currentName = NULL; | 498 CERTGeneralName *currentName = NULL; |
| 479 | 499 |
| 480 PORT_Assert(arena); | 500 PORT_Assert(arena); |
| 481 if (!encodedGenName || !arena) { | 501 if (!encodedGenName || !arena) { |
| 482 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 502 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 483 » return NULL; | 503 return NULL; |
| 484 } | 504 } |
| 485 /* TODO: mark arena */ | 505 /* TODO: mark arena */ |
| 486 while (*encodedGenName != NULL) { | 506 while (*encodedGenName != NULL) { |
| 487 » currentName = CERT_DecodeGeneralName(arena, *encodedGenName, NULL); | 507 currentName = CERT_DecodeGeneralName(arena, *encodedGenName, NULL); |
| 488 » if (currentName == NULL) | 508 if (currentName == NULL) |
| 489 » break; | 509 break; |
| 490 » if (head == NULL) { | 510 if (head == NULL) { |
| 491 » head = &(currentName->l); | 511 head = &(currentName->l); |
| 492 » tail = head; | 512 tail = head; |
| 493 » } | 513 } |
| 494 » currentName->l.next = head; | 514 currentName->l.next = head; |
| 495 » currentName->l.prev = tail; | 515 currentName->l.prev = tail; |
| 496 » tail = head->prev = tail->next = &(currentName->l); | 516 tail = head->prev = tail->next = &(currentName->l); |
| 497 » encodedGenName++; | 517 encodedGenName++; |
| 498 } | 518 } |
| 499 if (currentName) { | 519 if (currentName) { |
| 500 » /* TODO: unmark arena */ | 520 /* TODO: unmark arena */ |
| 501 » return CERT_GetNextGeneralName(currentName); | 521 return CERT_GetNextGeneralName(currentName); |
| 502 } | 522 } |
| 503 /* TODO: release arena to mark */ | 523 /* TODO: release arena to mark */ |
| 504 return NULL; | 524 return NULL; |
| 505 } | 525 } |
| 506 | 526 |
| 507 void | 527 void |
| 508 CERT_DestroyGeneralName(CERTGeneralName *name) | 528 CERT_DestroyGeneralName(CERTGeneralName *name) |
| 509 { | 529 { |
| 510 cert_DestroyGeneralNames(name); | 530 cert_DestroyGeneralNames(name); |
| 511 } | 531 } |
| 512 | 532 |
| 513 SECStatus | 533 SECStatus |
| 514 cert_DestroyGeneralNames(CERTGeneralName *name) | 534 cert_DestroyGeneralNames(CERTGeneralName *name) |
| 515 { | 535 { |
| 516 CERTGeneralName *first; | 536 CERTGeneralName *first; |
| 517 CERTGeneralName *next = NULL; | 537 CERTGeneralName *next = NULL; |
| 518 | |
| 519 | 538 |
| 520 first = name; | 539 first = name; |
| 521 do { | 540 do { |
| 522 » next = CERT_GetNextGeneralName(name); | 541 next = CERT_GetNextGeneralName(name); |
| 523 » PORT_Free(name); | 542 PORT_Free(name); |
| 524 » name = next; | 543 name = next; |
| 525 } while (name != first); | 544 } while (name != first); |
| 526 return SECSuccess; | 545 return SECSuccess; |
| 527 } | 546 } |
| 528 | 547 |
| 529 static SECItem * | 548 static SECItem * |
| 530 cert_EncodeNameConstraint(CERTNameConstraint *constraint, | 549 cert_EncodeNameConstraint(CERTNameConstraint *constraint, SECItem *dest, |
| 531 » » » SECItem *dest, | 550 PLArenaPool *arena) |
| 532 » » » PLArenaPool *arena) | |
| 533 { | 551 { |
| 534 PORT_Assert(arena); | 552 PORT_Assert(arena); |
| 535 if (dest == NULL) { | 553 if (dest == NULL) { |
| 536 » dest = PORT_ArenaZNew(arena, SECItem); | 554 dest = PORT_ArenaZNew(arena, SECItem); |
| 537 » if (dest == NULL) { | 555 if (dest == NULL) { |
| 538 » return NULL; | 556 return NULL; |
| 539 » } | 557 } |
| 540 } | 558 } |
| 541 CERT_EncodeGeneralName(&(constraint->name), &(constraint->DERName), arena); | 559 CERT_EncodeGeneralName(&(constraint->name), &(constraint->DERName), arena); |
| 542 | 560 |
| 543 dest = SEC_ASN1EncodeItem (arena, dest, constraint, | 561 dest = |
| 544 » » » CERTNameConstraintTemplate); | 562 SEC_ASN1EncodeItem(arena, dest, constraint, CERTNameConstraintTemplate); |
| 545 return dest; | 563 return dest; |
| 546 } | 564 } |
| 547 | 565 |
| 548 SECStatus | 566 SECStatus |
| 549 cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints, | 567 cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints, |
| 550 » » » PLArenaPool *arena, | 568 PLArenaPool *arena, SECItem ***dest, |
| 551 » » » » SECItem ***dest, | 569 PRBool permited) |
| 552 » » » » PRBool permited) | |
| 553 { | 570 { |
| 554 CERTNameConstraint *current_constraint = constraints; | 571 CERTNameConstraint *current_constraint = constraints; |
| 555 SECItem **items = NULL; | 572 SECItem **items = NULL; |
| 556 int count = 0; | 573 int count = 0; |
| 557 int i; | 574 int i; |
| 558 PRCList *head; | 575 PRCList *head; |
| 559 | 576 |
| 560 PORT_Assert(arena); | 577 PORT_Assert(arena); |
| 561 /* TODO: mark arena */ | 578 /* TODO: mark arena */ |
| 562 if (constraints != NULL) { | 579 if (constraints != NULL) { |
| 563 » count = 1; | 580 count = 1; |
| 564 } | 581 } |
| 565 head = &constraints->l; | 582 head = &constraints->l; |
| 566 while (current_constraint->l.next != head) { | 583 while (current_constraint->l.next != head) { |
| 567 » current_constraint = CERT_GetNextNameConstraint(current_constraint); | 584 current_constraint = CERT_GetNextNameConstraint(current_constraint); |
| 568 » ++count; | 585 ++count; |
| 569 } | 586 } |
| 570 current_constraint = CERT_GetNextNameConstraint(current_constraint); | 587 current_constraint = CERT_GetNextNameConstraint(current_constraint); |
| 571 items = PORT_ArenaZNewArray(arena, SECItem *, count + 1); | 588 items = PORT_ArenaZNewArray(arena, SECItem *, count + 1); |
| 572 if (items == NULL) { | 589 if (items == NULL) { |
| 573 » goto loser; | 590 goto loser; |
| 574 } | 591 } |
| 575 for (i = 0; i < count; i++) { | 592 for (i = 0; i < count; i++) { |
| 576 » items[i] = cert_EncodeNameConstraint(current_constraint, | 593 items[i] = cert_EncodeNameConstraint(current_constraint, |
| 577 » » » » » (SECItem *) NULL, arena); | 594 (SECItem *)NULL, arena); |
| 578 » if (items[i] == NULL) { | 595 if (items[i] == NULL) { |
| 579 » goto loser; | 596 goto loser; |
| 580 » } | 597 } |
| 581 » current_constraint = CERT_GetNextNameConstraint(current_constraint); | 598 current_constraint = CERT_GetNextNameConstraint(current_constraint); |
| 582 } | 599 } |
| 583 *dest = items; | 600 *dest = items; |
| 584 if (*dest == NULL) { | 601 if (*dest == NULL) { |
| 585 » goto loser; | 602 goto loser; |
| 586 } | 603 } |
| 587 /* TODO: unmark arena */ | 604 /* TODO: unmark arena */ |
| 588 return SECSuccess; | 605 return SECSuccess; |
| 589 loser: | 606 loser: |
| 590 /* TODO: release arena to mark */ | 607 /* TODO: release arena to mark */ |
| 591 return SECFailure; | 608 return SECFailure; |
| 592 } | 609 } |
| 593 | 610 |
| 594 SECStatus | 611 SECStatus |
| 595 cert_EncodeNameConstraints(CERTNameConstraints *constraints, | 612 cert_EncodeNameConstraints(CERTNameConstraints *constraints, PLArenaPool *arena, |
| 596 » » » PLArenaPool *arena, | 613 SECItem *dest) |
| 597 » » » SECItem *dest) | |
| 598 { | 614 { |
| 599 SECStatus rv = SECSuccess; | 615 SECStatus rv = SECSuccess; |
| 600 | 616 |
| 601 PORT_Assert(arena); | 617 PORT_Assert(arena); |
| 602 /* TODO: mark arena */ | 618 /* TODO: mark arena */ |
| 603 if (constraints->permited != NULL) { | 619 if (constraints->permited != NULL) { |
| 604 » rv = cert_EncodeNameConstraintSubTree(constraints->permited, arena, | 620 rv = cert_EncodeNameConstraintSubTree( |
| 605 » » » » » &constraints->DERPermited, | 621 constraints->permited, arena, &constraints->DERPermited, PR_TRUE); |
| 606 » » » » » PR_TRUE); | 622 if (rv == SECFailure) { |
| 607 » if (rv == SECFailure) { | 623 goto loser; |
| 608 » goto loser; | 624 } |
| 609 » } | |
| 610 } | 625 } |
| 611 if (constraints->excluded != NULL) { | 626 if (constraints->excluded != NULL) { |
| 612 » rv = cert_EncodeNameConstraintSubTree(constraints->excluded, arena, | 627 rv = cert_EncodeNameConstraintSubTree( |
| 613 » » » » » &constraints->DERExcluded, | 628 constraints->excluded, arena, &constraints->DERExcluded, PR_FALSE); |
| 614 » » » » » PR_FALSE); | 629 if (rv == SECFailure) { |
| 615 » if (rv == SECFailure) { | 630 goto loser; |
| 616 » goto loser; | 631 } |
| 617 » } | |
| 618 } | 632 } |
| 619 dest = SEC_ASN1EncodeItem(arena, dest, constraints, | 633 dest = SEC_ASN1EncodeItem(arena, dest, constraints, |
| 620 » » » CERTNameConstraintsTemplate); | 634 CERTNameConstraintsTemplate); |
| 621 if (dest == NULL) { | 635 if (dest == NULL) { |
| 622 » goto loser; | 636 goto loser; |
| 623 } | 637 } |
| 624 /* TODO: unmark arena */ | 638 /* TODO: unmark arena */ |
| 625 return SECSuccess; | 639 return SECSuccess; |
| 626 loser: | 640 loser: |
| 627 /* TODO: release arena to mark */ | 641 /* TODO: release arena to mark */ |
| 628 return SECFailure; | 642 return SECFailure; |
| 629 } | 643 } |
| 630 | 644 |
| 631 | |
| 632 CERTNameConstraint * | 645 CERTNameConstraint * |
| 633 cert_DecodeNameConstraint(PLArenaPool *reqArena, | 646 cert_DecodeNameConstraint(PLArenaPool *reqArena, SECItem *encodedConstraint) |
| 634 » » » SECItem *encodedConstraint) | |
| 635 { | 647 { |
| 636 CERTNameConstraint *constraint; | 648 CERTNameConstraint *constraint; |
| 637 SECStatus rv = SECSuccess; | 649 SECStatus rv = SECSuccess; |
| 638 CERTGeneralName *temp; | 650 CERTGeneralName *temp; |
| 639 SECItem* newEncodedConstraint; | 651 SECItem *newEncodedConstraint; |
| 640 | 652 |
| 641 if (!reqArena) { | 653 if (!reqArena) { |
| 642 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 654 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 643 return NULL; | 655 return NULL; |
| 644 } | 656 } |
| 645 newEncodedConstraint = SECITEM_ArenaDupItem(reqArena, encodedConstraint); | 657 newEncodedConstraint = SECITEM_ArenaDupItem(reqArena, encodedConstraint); |
| 646 if (!newEncodedConstraint) { | 658 if (!newEncodedConstraint) { |
| 647 return NULL; | 659 return NULL; |
| 648 } | 660 } |
| 649 /* TODO: mark arena */ | 661 /* TODO: mark arena */ |
| 650 constraint = PORT_ArenaZNew(reqArena, CERTNameConstraint); | 662 constraint = PORT_ArenaZNew(reqArena, CERTNameConstraint); |
| 651 if (!constraint) | 663 if (!constraint) |
| 652 » goto loser; | 664 goto loser; |
| 653 rv = SEC_QuickDERDecodeItem(reqArena, constraint, | 665 rv = SEC_QuickDERDecodeItem( |
| 654 CERTNameConstraintTemplate, | 666 reqArena, constraint, CERTNameConstraintTemplate, newEncodedConstraint); |
| 655 newEncodedConstraint); | |
| 656 if (rv != SECSuccess) { | 667 if (rv != SECSuccess) { |
| 657 » goto loser; | 668 goto loser; |
| 658 } | 669 } |
| 659 temp = CERT_DecodeGeneralName(reqArena, &(constraint->DERName), | 670 temp = CERT_DecodeGeneralName(reqArena, &(constraint->DERName), |
| 660 &(constraint->name)); | 671 &(constraint->name)); |
| 661 if (temp != &(constraint->name)) { | 672 if (temp != &(constraint->name)) { |
| 662 » goto loser; | 673 goto loser; |
| 663 } | 674 } |
| 664 | 675 |
| 665 /* ### sjlee: since the name constraint contains only one | 676 /* ### sjlee: since the name constraint contains only one |
| 666 * CERTGeneralName, the list within CERTGeneralName shouldn't | 677 * CERTGeneralName, the list within CERTGeneralName shouldn't |
| 667 * point anywhere else. Otherwise, bad things will happen. | 678 * point anywhere else. Otherwise, bad things will happen. |
| 668 */ | 679 */ |
| 669 constraint->name.l.prev = constraint->name.l.next = &(constraint->name.l); | 680 constraint->name.l.prev = constraint->name.l.next = &(constraint->name.l); |
| 670 /* TODO: unmark arena */ | 681 /* TODO: unmark arena */ |
| 671 return constraint; | 682 return constraint; |
| 672 loser: | 683 loser: |
| 673 /* TODO: release arena back to mark */ | 684 /* TODO: release arena back to mark */ |
| 674 return NULL; | 685 return NULL; |
| 675 } | 686 } |
| 676 | 687 |
| 677 static CERTNameConstraint * | 688 static CERTNameConstraint * |
| 678 cert_DecodeNameConstraintSubTree(PLArenaPool *arena, | 689 cert_DecodeNameConstraintSubTree(PLArenaPool *arena, SECItem **subTree, |
| 679 » » » » SECItem **subTree, | 690 PRBool permited) |
| 680 » » » » PRBool permited) | |
| 681 { | 691 { |
| 682 CERTNameConstraint *current = NULL; | 692 CERTNameConstraint *current = NULL; |
| 683 CERTNameConstraint *first = NULL; | 693 CERTNameConstraint *first = NULL; |
| 684 CERTNameConstraint *last = NULL; | 694 CERTNameConstraint *last = NULL; |
| 685 int i = 0; | 695 int i = 0; |
| 686 | 696 |
| 687 PORT_Assert(arena); | 697 PORT_Assert(arena); |
| 688 /* TODO: mark arena */ | 698 /* TODO: mark arena */ |
| 689 while (subTree[i] != NULL) { | 699 while (subTree[i] != NULL) { |
| 690 » current = cert_DecodeNameConstraint(arena, subTree[i]); | 700 current = cert_DecodeNameConstraint(arena, subTree[i]); |
| 691 » if (current == NULL) { | 701 if (current == NULL) { |
| 692 » goto loser; | 702 goto loser; |
| 693 » } | 703 } |
| 694 » if (first == NULL) { | 704 if (first == NULL) { |
| 695 » first = current; | 705 first = current; |
| 696 » } else { | 706 } else { |
| 697 » current->l.prev = &(last->l); | 707 current->l.prev = &(last->l); |
| 698 » last->l.next = &(current->l); | 708 last->l.next = &(current->l); |
| 699 » } | 709 } |
| 700 » last = current; | 710 last = current; |
| 701 » i++; | 711 i++; |
| 702 } | 712 } |
| 703 first->l.prev = &(last->l); | 713 first->l.prev = &(last->l); |
| 704 last->l.next = &(first->l); | 714 last->l.next = &(first->l); |
| 705 /* TODO: unmark arena */ | 715 /* TODO: unmark arena */ |
| 706 return first; | 716 return first; |
| 707 loser: | 717 loser: |
| 708 /* TODO: release arena back to mark */ | 718 /* TODO: release arena back to mark */ |
| 709 return NULL; | 719 return NULL; |
| 710 } | 720 } |
| 711 | 721 |
| 712 CERTNameConstraints * | 722 CERTNameConstraints * |
| 713 cert_DecodeNameConstraints(PLArenaPool *reqArena, | 723 cert_DecodeNameConstraints(PLArenaPool *reqArena, |
| 714 » » » const SECItem *encodedConstraints) | 724 const SECItem *encodedConstraints) |
| 715 { | 725 { |
| 716 CERTNameConstraints *constraints; | 726 CERTNameConstraints *constraints; |
| 717 SECStatus rv; | 727 SECStatus rv; |
| 718 SECItem* newEncodedConstraints; | 728 SECItem *newEncodedConstraints; |
| 719 | 729 |
| 720 if (!reqArena) { | 730 if (!reqArena) { |
| 721 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 731 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 722 return NULL; | 732 return NULL; |
| 723 } | 733 } |
| 724 PORT_Assert(encodedConstraints); | 734 PORT_Assert(encodedConstraints); |
| 725 newEncodedConstraints = SECITEM_ArenaDupItem(reqArena, encodedConstraints); | 735 newEncodedConstraints = SECITEM_ArenaDupItem(reqArena, encodedConstraints); |
| 726 | 736 |
| 727 /* TODO: mark arena */ | 737 /* TODO: mark arena */ |
| 728 constraints = PORT_ArenaZNew(reqArena, CERTNameConstraints); | 738 constraints = PORT_ArenaZNew(reqArena, CERTNameConstraints); |
| 729 if (constraints == NULL) { | 739 if (constraints == NULL) { |
| 730 » goto loser; | 740 goto loser; |
| 731 } | 741 } |
| 732 rv = SEC_QuickDERDecodeItem(reqArena, constraints, | 742 rv = SEC_QuickDERDecodeItem(reqArena, constraints, |
| 733 CERTNameConstraintsTemplate, | 743 CERTNameConstraintsTemplate, |
| 734 newEncodedConstraints); | 744 newEncodedConstraints); |
| 735 if (rv != SECSuccess) { | 745 if (rv != SECSuccess) { |
| 736 » goto loser; | 746 goto loser; |
| 737 } | 747 } |
| 738 if (constraints->DERPermited != NULL && | 748 if (constraints->DERPermited != NULL && |
| 739 constraints->DERPermited[0] != NULL) { | 749 constraints->DERPermited[0] != NULL) { |
| 740 » constraints->permited = | 750 constraints->permited = cert_DecodeNameConstraintSubTree( |
| 741 » cert_DecodeNameConstraintSubTree(reqArena, | 751 reqArena, constraints->DERPermited, PR_TRUE); |
| 742 constraints->DERPermited, | 752 if (constraints->permited == NULL) { |
| 743 PR_TRUE); | 753 goto loser; |
| 744 » if (constraints->permited == NULL) { | 754 } |
| 745 » goto loser; | |
| 746 » } | |
| 747 } | 755 } |
| 748 if (constraints->DERExcluded != NULL && | 756 if (constraints->DERExcluded != NULL && |
| 749 constraints->DERExcluded[0] != NULL) { | 757 constraints->DERExcluded[0] != NULL) { |
| 750 » constraints->excluded = | 758 constraints->excluded = cert_DecodeNameConstraintSubTree( |
| 751 » cert_DecodeNameConstraintSubTree(reqArena, | 759 reqArena, constraints->DERExcluded, PR_FALSE); |
| 752 constraints->DERExcluded, | 760 if (constraints->excluded == NULL) { |
| 753 PR_FALSE); | 761 goto loser; |
| 754 » if (constraints->excluded == NULL) { | 762 } |
| 755 » goto loser; | |
| 756 » } | |
| 757 } | 763 } |
| 758 /* TODO: unmark arena */ | 764 /* TODO: unmark arena */ |
| 759 return constraints; | 765 return constraints; |
| 760 loser: | 766 loser: |
| 761 /* TODO: release arena back to mark */ | 767 /* TODO: release arena back to mark */ |
| 762 return NULL; | 768 return NULL; |
| 763 } | 769 } |
| 764 | 770 |
| 765 /* Copy a chain of one or more general names to a destination chain. | 771 /* Copy a chain of one or more general names to a destination chain. |
| 766 ** Caller has allocated at least the first destination GeneralName struct. | 772 ** Caller has allocated at least the first destination GeneralName struct. |
| 767 ** Both source and destination chains are circular doubly-linked lists. | 773 ** Both source and destination chains are circular doubly-linked lists. |
| 768 ** The first source struct is copied to the first destination struct. | 774 ** The first source struct is copied to the first destination struct. |
| 769 ** If the source chain has more than one member, and the destination chain | 775 ** If the source chain has more than one member, and the destination chain |
| 770 ** has only one member, then this function allocates new structs for all but | 776 ** has only one member, then this function allocates new structs for all but |
| 771 ** the first copy from the arena and links them into the destination list. | 777 ** the first copy from the arena and links them into the destination list. |
| 772 ** If the destination struct is part of a list with more than one member, | 778 ** If the destination struct is part of a list with more than one member, |
| 773 ** then this function traverses both the source and destination lists, | 779 ** then this function traverses both the source and destination lists, |
| 774 ** copying each source struct to the corresponding dest struct. | 780 ** copying each source struct to the corresponding dest struct. |
| 775 ** In that case, the destination list MUST contain at least as many | 781 ** In that case, the destination list MUST contain at least as many |
| 776 ** structs as the source list or some dest entries will be overwritten. | 782 ** structs as the source list or some dest entries will be overwritten. |
| 777 */ | 783 */ |
| 778 SECStatus | 784 SECStatus |
| 779 CERT_CopyGeneralName(PLArenaPool *arena, | 785 CERT_CopyGeneralName(PLArenaPool *arena, CERTGeneralName *dest, |
| 780 » » CERTGeneralName *dest, | 786 CERTGeneralName *src) |
| 781 » » CERTGeneralName *src) | |
| 782 { | 787 { |
| 783 SECStatus rv; | 788 SECStatus rv; |
| 784 CERTGeneralName *destHead = dest; | 789 CERTGeneralName *destHead = dest; |
| 785 CERTGeneralName *srcHead = src; | 790 CERTGeneralName *srcHead = src; |
| 786 | 791 |
| 787 PORT_Assert(dest != NULL); | 792 PORT_Assert(dest != NULL); |
| 788 if (!dest) { | 793 if (!dest) { |
| 789 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 794 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 790 return SECFailure; | 795 return SECFailure; |
| 791 } | 796 } |
| 792 /* TODO: mark arena */ | 797 /* TODO: mark arena */ |
| 793 do { | 798 do { |
| 794 » rv = cert_CopyOneGeneralName(arena, dest, src); | 799 rv = cert_CopyOneGeneralName(arena, dest, src); |
| 795 » if (rv != SECSuccess) | 800 if (rv != SECSuccess) |
| 796 » goto loser; | 801 goto loser; |
| 797 » src = CERT_GetNextGeneralName(src); | 802 src = CERT_GetNextGeneralName(src); |
| 798 » /* if there is only one general name, we shouldn't do this */ | 803 /* if there is only one general name, we shouldn't do this */ |
| 799 » if (src != srcHead) { | 804 if (src != srcHead) { |
| 800 » if (dest->l.next == &destHead->l) { | 805 if (dest->l.next == &destHead->l) { |
| 801 » » CERTGeneralName *temp; | 806 CERTGeneralName *temp; |
| 802 » » temp = CERT_NewGeneralName(arena, (CERTGeneralNameType)0); | 807 temp = CERT_NewGeneralName(arena, (CERTGeneralNameType)0); |
| 803 » » if (!temp) | 808 if (!temp) |
| 804 » » goto loser; | 809 goto loser; |
| 805 » » temp->l.next = &destHead->l; | 810 temp->l.next = &destHead->l; |
| 806 » » temp->l.prev = &dest->l; | 811 temp->l.prev = &dest->l; |
| 807 » » destHead->l.prev = &temp->l; | 812 destHead->l.prev = &temp->l; |
| 808 » » dest->l.next = &temp->l; | 813 dest->l.next = &temp->l; |
| 809 » » dest = temp; | 814 dest = temp; |
| 810 » } else { | 815 } else { |
| 811 » » dest = CERT_GetNextGeneralName(dest); | 816 dest = CERT_GetNextGeneralName(dest); |
| 812 » } | 817 } |
| 813 » } | 818 } |
| 814 } while (src != srcHead && rv == SECSuccess); | 819 } while (src != srcHead && rv == SECSuccess); |
| 815 /* TODO: unmark arena */ | 820 /* TODO: unmark arena */ |
| 816 return rv; | 821 return rv; |
| 817 loser: | 822 loser: |
| 818 /* TODO: release back to mark */ | 823 /* TODO: release back to mark */ |
| 819 return SECFailure; | 824 return SECFailure; |
| 820 } | 825 } |
| 821 | 826 |
| 822 | |
| 823 CERTGeneralNameList * | 827 CERTGeneralNameList * |
| 824 CERT_DupGeneralNameList(CERTGeneralNameList *list) | 828 CERT_DupGeneralNameList(CERTGeneralNameList *list) |
| 825 { | 829 { |
| 826 if (list != NULL) { | 830 if (list != NULL) { |
| 827 » PZ_Lock(list->lock); | 831 PZ_Lock(list->lock); |
| 828 » list->refCount++; | 832 list->refCount++; |
| 829 » PZ_Unlock(list->lock); | 833 PZ_Unlock(list->lock); |
| 830 } | 834 } |
| 831 return list; | 835 return list; |
| 832 } | 836 } |
| 833 | 837 |
| 834 /* Allocate space and copy CERTNameConstraint from src to dest */ | 838 /* Allocate space and copy CERTNameConstraint from src to dest */ |
| 835 CERTNameConstraint * | 839 CERTNameConstraint * |
| 836 CERT_CopyNameConstraint(PLArenaPool *arena, | 840 CERT_CopyNameConstraint(PLArenaPool *arena, CERTNameConstraint *dest, |
| 837 » » » CERTNameConstraint *dest, | 841 CERTNameConstraint *src) |
| 838 » » » CERTNameConstraint *src) | |
| 839 { | 842 { |
| 840 SECStatus rv; | 843 SECStatus rv; |
| 841 | 844 |
| 842 /* TODO: mark arena */ | 845 /* TODO: mark arena */ |
| 843 if (dest == NULL) { | 846 if (dest == NULL) { |
| 844 » dest = PORT_ArenaZNew(arena, CERTNameConstraint); | 847 dest = PORT_ArenaZNew(arena, CERTNameConstraint); |
| 845 » if (!dest) | 848 if (!dest) |
| 846 » goto loser; | 849 goto loser; |
| 847 » /* mark that it is not linked */ | 850 /* mark that it is not linked */ |
| 848 » dest->name.l.prev = dest->name.l.next = &(dest->name.l); | 851 dest->name.l.prev = dest->name.l.next = &(dest->name.l); |
| 849 } | 852 } |
| 850 rv = CERT_CopyGeneralName(arena, &dest->name, &src->name); | 853 rv = CERT_CopyGeneralName(arena, &dest->name, &src->name); |
| 851 if (rv != SECSuccess) { | 854 if (rv != SECSuccess) { |
| 852 » goto loser; | 855 goto loser; |
| 853 } | 856 } |
| 854 rv = SECITEM_CopyItem(arena, &dest->DERName, &src->DERName); | 857 rv = SECITEM_CopyItem(arena, &dest->DERName, &src->DERName); |
| 855 if (rv != SECSuccess) { | 858 if (rv != SECSuccess) { |
| 856 » goto loser; | 859 goto loser; |
| 857 } | 860 } |
| 858 rv = SECITEM_CopyItem(arena, &dest->min, &src->min); | 861 rv = SECITEM_CopyItem(arena, &dest->min, &src->min); |
| 859 if (rv != SECSuccess) { | 862 if (rv != SECSuccess) { |
| 860 » goto loser; | 863 goto loser; |
| 861 } | 864 } |
| 862 rv = SECITEM_CopyItem(arena, &dest->max, &src->max); | 865 rv = SECITEM_CopyItem(arena, &dest->max, &src->max); |
| 863 if (rv != SECSuccess) { | 866 if (rv != SECSuccess) { |
| 864 » goto loser; | 867 goto loser; |
| 865 } | 868 } |
| 866 dest->l.prev = dest->l.next = &dest->l; | 869 dest->l.prev = dest->l.next = &dest->l; |
| 867 /* TODO: unmark arena */ | 870 /* TODO: unmark arena */ |
| 868 return dest; | 871 return dest; |
| 869 loser: | 872 loser: |
| 870 /* TODO: release arena to mark */ | 873 /* TODO: release arena to mark */ |
| 871 return NULL; | 874 return NULL; |
| 872 } | 875 } |
| 873 | 876 |
| 874 | |
| 875 CERTGeneralName * | 877 CERTGeneralName * |
| 876 cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2) | 878 cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2) |
| 877 { | 879 { |
| 878 PRCList *begin1; | 880 PRCList *begin1; |
| 879 PRCList *begin2; | 881 PRCList *begin2; |
| 880 PRCList *end1; | 882 PRCList *end1; |
| 881 PRCList *end2; | 883 PRCList *end2; |
| 882 | 884 |
| 883 if (list1 == NULL){ | 885 if (list1 == NULL) { |
| 884 » return list2; | 886 return list2; |
| 885 } else if (list2 == NULL) { | 887 } else if (list2 == NULL) { |
| 886 » return list1; | 888 return list1; |
| 887 } else { | 889 } else { |
| 888 » begin1 = &list1->l; | 890 begin1 = &list1->l; |
| 889 » begin2 = &list2->l; | 891 begin2 = &list2->l; |
| 890 » end1 = list1->l.prev; | 892 end1 = list1->l.prev; |
| 891 » end2 = list2->l.prev; | 893 end2 = list2->l.prev; |
| 892 » end1->next = begin2; | 894 end1->next = begin2; |
| 893 » end2->next = begin1; | 895 end2->next = begin1; |
| 894 » begin1->prev = end2; | 896 begin1->prev = end2; |
| 895 » begin2->prev = end1; | 897 begin2->prev = end1; |
| 896 » return list1; | 898 return list1; |
| 897 } | 899 } |
| 898 } | 900 } |
| 899 | 901 |
| 900 | |
| 901 CERTNameConstraint * | 902 CERTNameConstraint * |
| 902 cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list
2) | 903 cert_CombineConstraintsLists(CERTNameConstraint *list1, |
| 904 CERTNameConstraint *list2) |
| 903 { | 905 { |
| 904 PRCList *begin1; | 906 PRCList *begin1; |
| 905 PRCList *begin2; | 907 PRCList *begin2; |
| 906 PRCList *end1; | 908 PRCList *end1; |
| 907 PRCList *end2; | 909 PRCList *end2; |
| 908 | 910 |
| 909 if (list1 == NULL){ | 911 if (list1 == NULL) { |
| 910 » return list2; | 912 return list2; |
| 911 } else if (list2 == NULL) { | 913 } else if (list2 == NULL) { |
| 912 » return list1; | 914 return list1; |
| 913 } else { | 915 } else { |
| 914 » begin1 = &list1->l; | 916 begin1 = &list1->l; |
| 915 » begin2 = &list2->l; | 917 begin2 = &list2->l; |
| 916 » end1 = list1->l.prev; | 918 end1 = list1->l.prev; |
| 917 » end2 = list2->l.prev; | 919 end2 = list2->l.prev; |
| 918 » end1->next = begin2; | 920 end1->next = begin2; |
| 919 » end2->next = begin1; | 921 end2->next = begin1; |
| 920 » begin1->prev = end2; | 922 begin1->prev = end2; |
| 921 » begin2->prev = end1; | 923 begin2->prev = end1; |
| 922 » return list1; | 924 return list1; |
| 923 } | 925 } |
| 924 } | 926 } |
| 925 | 927 |
| 926 | |
| 927 /* Add a CERTNameConstraint to the CERTNameConstraint list */ | 928 /* Add a CERTNameConstraint to the CERTNameConstraint list */ |
| 928 CERTNameConstraint * | 929 CERTNameConstraint * |
| 929 CERT_AddNameConstraint(CERTNameConstraint *list, | 930 CERT_AddNameConstraint(CERTNameConstraint *list, CERTNameConstraint *constraint) |
| 930 » » CERTNameConstraint *constraint) | |
| 931 { | 931 { |
| 932 PORT_Assert(constraint != NULL); | 932 PORT_Assert(constraint != NULL); |
| 933 constraint->l.next = constraint->l.prev = &constraint->l; | 933 constraint->l.next = constraint->l.prev = &constraint->l; |
| 934 list = cert_CombineConstraintsLists(list, constraint); | 934 list = cert_CombineConstraintsLists(list, constraint); |
| 935 return list; | 935 return list; |
| 936 } | 936 } |
| 937 | 937 |
| 938 | |
| 939 SECStatus | 938 SECStatus |
| 940 CERT_GetNameConstraintByType (CERTNameConstraint *constraints, | 939 CERT_GetNameConstraintByType(CERTNameConstraint *constraints, |
| 941 » » » CERTGeneralNameType type, | 940 CERTGeneralNameType type, |
| 942 » » » CERTNameConstraint **returnList, | 941 CERTNameConstraint **returnList, |
| 943 » » » PLArenaPool *arena) | 942 PLArenaPool *arena) |
| 944 { | 943 { |
| 945 CERTNameConstraint *current = NULL; | 944 CERTNameConstraint *current = NULL; |
| 946 void *mark = NULL; | 945 void *mark = NULL; |
| 947 | 946 |
| 948 *returnList = NULL; | 947 *returnList = NULL; |
| 949 if (!constraints) | 948 if (!constraints) |
| 950 » return SECSuccess; | 949 return SECSuccess; |
| 951 | 950 |
| 952 mark = PORT_ArenaMark(arena); | 951 mark = PORT_ArenaMark(arena); |
| 953 | 952 |
| 954 current = constraints; | 953 current = constraints; |
| 955 do { | 954 do { |
| 956 » PORT_Assert(current->name.type); | 955 PORT_Assert(current->name.type); |
| 957 » if (current->name.type == type) { | 956 if (current->name.type == type) { |
| 958 » CERTNameConstraint *temp; | 957 CERTNameConstraint *temp; |
| 959 » temp = CERT_CopyNameConstraint(arena, NULL, current); | 958 temp = CERT_CopyNameConstraint(arena, NULL, current); |
| 960 » if (temp == NULL) | 959 if (temp == NULL) |
| 961 » » goto loser; | 960 goto loser; |
| 962 » *returnList = CERT_AddNameConstraint(*returnList, temp); | 961 *returnList = CERT_AddNameConstraint(*returnList, temp); |
| 963 » } | 962 } |
| 964 » current = CERT_GetNextNameConstraint(current); | 963 current = CERT_GetNextNameConstraint(current); |
| 965 } while (current != constraints); | 964 } while (current != constraints); |
| 966 PORT_ArenaUnmark(arena, mark); | 965 PORT_ArenaUnmark(arena, mark); |
| 967 return SECSuccess; | 966 return SECSuccess; |
| 968 | 967 |
| 969 loser: | 968 loser: |
| 970 PORT_ArenaRelease(arena, mark); | 969 PORT_ArenaRelease(arena, mark); |
| 971 return SECFailure; | 970 return SECFailure; |
| 972 } | 971 } |
| 973 | 972 |
| 974 void * | 973 void * |
| 975 CERT_GetGeneralNameByType (CERTGeneralName *genNames, | 974 CERT_GetGeneralNameByType(CERTGeneralName *genNames, CERTGeneralNameType type, |
| 976 » » » CERTGeneralNameType type, PRBool derFormat) | 975 PRBool derFormat) |
| 977 { | 976 { |
| 978 CERTGeneralName *current; | 977 CERTGeneralName *current; |
| 979 | 978 |
| 980 if (!genNames) | 979 if (!genNames) |
| 981 » return NULL; | 980 return NULL; |
| 982 current = genNames; | 981 current = genNames; |
| 983 | 982 |
| 984 do { | 983 do { |
| 985 » if (current->type == type) { | 984 if (current->type == type) { |
| 986 » switch (type) { | 985 switch (type) { |
| 987 » case certDNSName: | 986 case certDNSName: |
| 988 » case certEDIPartyName: | 987 case certEDIPartyName: |
| 989 » case certIPAddress: | 988 case certIPAddress: |
| 990 » case certRegisterID: | 989 case certRegisterID: |
| 991 » case certRFC822Name: | 990 case certRFC822Name: |
| 992 » case certX400Address: | 991 case certX400Address: |
| 993 » case certURI: | 992 case certURI: |
| 994 » » return (void *)¤t->name.other; /* SECItem * */ | 993 return (void *)¤t->name.other; /* SECItem * */ |
| 995 | 994 |
| 996 » case certOtherName: | 995 case certOtherName: |
| 997 » » return (void *)¤t->name.OthName; /* OthName * */ | 996 return (void *)¤t->name.OthName; /* OthName * */ |
| 998 | 997 |
| 999 » case certDirectoryName: | 998 case certDirectoryName: |
| 1000 » » return derFormat | 999 return derFormat |
| 1001 » » ? (void *)¤t->derDirectoryName /* SECItem * */ | 1000 ? (void *)¤t |
| 1002 » » : (void *)¤t->name.directoryName; /* CERTName * */ | 1001 ->derDirectoryName /* SECItem * */ |
| 1003 » } | 1002 : (void *)¤t->name |
| 1004 » PORT_Assert(0); | 1003 .directoryName; /* CERTName * */ |
| 1005 » return NULL; | 1004 } |
| 1006 » } | 1005 PORT_Assert(0); |
| 1007 » current = CERT_GetNextGeneralName(current); | 1006 return NULL; |
| 1007 } |
| 1008 current = CERT_GetNextGeneralName(current); |
| 1008 } while (current != genNames); | 1009 } while (current != genNames); |
| 1009 return NULL; | 1010 return NULL; |
| 1010 } | 1011 } |
| 1011 | 1012 |
| 1012 int | 1013 int |
| 1013 CERT_GetNamesLength(CERTGeneralName *names) | 1014 CERT_GetNamesLength(CERTGeneralName *names) |
| 1014 { | 1015 { |
| 1015 int length = 0; | 1016 int length = 0; |
| 1016 CERTGeneralName *first; | 1017 CERTGeneralName *first; |
| 1017 | 1018 |
| 1018 first = names; | 1019 first = names; |
| 1019 if (names != NULL) { | 1020 if (names != NULL) { |
| 1020 » do { | 1021 do { |
| 1021 » length++; | 1022 length++; |
| 1022 » names = CERT_GetNextGeneralName(names); | 1023 names = CERT_GetNextGeneralName(names); |
| 1023 » } while (names != first); | 1024 } while (names != first); |
| 1024 } | 1025 } |
| 1025 return length; | 1026 return length; |
| 1026 } | 1027 } |
| 1027 | 1028 |
| 1028 /* Creates new GeneralNames for any email addresses found in the | 1029 /* Creates new GeneralNames for any email addresses found in the |
| 1029 ** input DN, and links them onto the list for the DN. | 1030 ** input DN, and links them onto the list for the DN. |
| 1030 */ | 1031 */ |
| 1031 SECStatus | 1032 SECStatus |
| 1032 cert_ExtractDNEmailAddrs(CERTGeneralName *name, PLArenaPool *arena) | 1033 cert_ExtractDNEmailAddrs(CERTGeneralName *name, PLArenaPool *arena) |
| 1033 { | 1034 { |
| 1034 CERTGeneralName *nameList = NULL; | 1035 CERTGeneralName *nameList = NULL; |
| 1035 const CERTRDN **nRDNs = (const CERTRDN **)(name->name.directoryName.rdns); | 1036 const CERTRDN **nRDNs = (const CERTRDN **)(name->name.directoryName.rdns); |
| 1036 SECStatus rv = SECSuccess; | 1037 SECStatus rv = SECSuccess; |
| 1037 | 1038 |
| 1038 PORT_Assert(name->type == certDirectoryName); | 1039 PORT_Assert(name->type == certDirectoryName); |
| 1039 if (name->type != certDirectoryName) { | 1040 if (name->type != certDirectoryName) { |
| 1040 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1041 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1041 » return SECFailure; | 1042 return SECFailure; |
| 1042 } | 1043 } |
| 1043 /* TODO: mark arena */ | 1044 /* TODO: mark arena */ |
| 1044 while (nRDNs && *nRDNs) { /* loop over RDNs */ | 1045 while (nRDNs && *nRDNs) { /* loop over RDNs */ |
| 1045 » const CERTRDN *nRDN = *nRDNs++; | 1046 const CERTRDN *nRDN = *nRDNs++; |
| 1046 » CERTAVA **nAVAs = nRDN->avas; | 1047 CERTAVA **nAVAs = nRDN->avas; |
| 1047 » while (nAVAs && *nAVAs) { /* loop over AVAs */ | 1048 while (nAVAs && *nAVAs) { /* loop over AVAs */ |
| 1048 » int tag; | 1049 int tag; |
| 1049 » CERTAVA *nAVA = *nAVAs++; | 1050 CERTAVA *nAVA = *nAVAs++; |
| 1050 » tag = CERT_GetAVATag(nAVA); | 1051 tag = CERT_GetAVATag(nAVA); |
| 1051 » if ( tag == SEC_OID_PKCS9_EMAIL_ADDRESS || | 1052 if (tag == SEC_OID_PKCS9_EMAIL_ADDRESS || |
| 1052 » » tag == SEC_OID_RFC1274_MAIL) { /* email AVA */ | 1053 tag == SEC_OID_RFC1274_MAIL) { /* email AVA */ |
| 1053 » » CERTGeneralName *newName = NULL; | 1054 CERTGeneralName *newName = NULL; |
| 1054 » » SECItem *avaValue = CERT_DecodeAVAValue(&nAVA->value); | 1055 SECItem *avaValue = CERT_DecodeAVAValue(&nAVA->value); |
| 1055 » » if (!avaValue) | 1056 if (!avaValue) |
| 1056 » » goto loser; | 1057 goto loser; |
| 1057 » » rv = SECFailure; | 1058 rv = SECFailure; |
| 1058 newName = CERT_NewGeneralName(arena, certRFC822Name); | 1059 newName = CERT_NewGeneralName(arena, certRFC822Name); |
| 1059 » » if (newName) { | 1060 if (newName) { |
| 1060 » » rv = SECITEM_CopyItem(arena, &newName->name.other, avaValue); | 1061 rv = |
| 1061 » » } | 1062 SECITEM_CopyItem(arena, &newName->name.other, avaValue); |
| 1062 » » SECITEM_FreeItem(avaValue, PR_TRUE); | 1063 } |
| 1063 » » if (rv != SECSuccess) | 1064 SECITEM_FreeItem(avaValue, PR_TRUE); |
| 1064 » » goto loser; | 1065 if (rv != SECSuccess) |
| 1065 » » nameList = cert_CombineNamesLists(nameList, newName); | 1066 goto loser; |
| 1066 » } /* handle one email AVA */ | 1067 nameList = cert_CombineNamesLists(nameList, newName); |
| 1067 » } /* loop over AVAs */ | 1068 } /* handle one email AVA */ |
| 1068 } /* loop over RDNs */ | 1069 } /* loop over AVAs */ |
| 1070 } /* loop over RDNs */ |
| 1069 /* combine new names with old one. */ | 1071 /* combine new names with old one. */ |
| 1070 name = cert_CombineNamesLists(name, nameList); | 1072 name = cert_CombineNamesLists(name, nameList); |
| 1071 /* TODO: unmark arena */ | 1073 /* TODO: unmark arena */ |
| 1072 return SECSuccess; | 1074 return SECSuccess; |
| 1073 | 1075 |
| 1074 loser: | 1076 loser: |
| 1075 /* TODO: release arena back to mark */ | 1077 /* TODO: release arena back to mark */ |
| 1076 return SECFailure; | 1078 return SECFailure; |
| 1077 } | 1079 } |
| 1078 | 1080 |
| 1079 /* Extract all names except Subject Common Name from a cert | 1081 /* Extract all names except Subject Common Name from a cert |
| 1080 ** in preparation for a name constraints test. | 1082 ** in preparation for a name constraints test. |
| 1081 */ | 1083 */ |
| 1082 CERTGeneralName * | 1084 CERTGeneralName * |
| 1083 CERT_GetCertificateNames(CERTCertificate *cert, PLArenaPool *arena) | 1085 CERT_GetCertificateNames(CERTCertificate *cert, PLArenaPool *arena) |
| 1084 { | 1086 { |
| 1085 return CERT_GetConstrainedCertificateNames(cert, arena, PR_FALSE); | 1087 return CERT_GetConstrainedCertificateNames(cert, arena, PR_FALSE); |
| 1086 } | 1088 } |
| 1087 | 1089 |
| 1088 /* This function is called by CERT_VerifyCertChain to extract all | 1090 /* This function is called by CERT_VerifyCertChain to extract all |
| 1089 ** names from a cert in preparation for a name constraints test. | 1091 ** names from a cert in preparation for a name constraints test. |
| 1090 */ | 1092 */ |
| 1091 CERTGeneralName * | 1093 CERTGeneralName * |
| 1092 CERT_GetConstrainedCertificateNames(const CERTCertificate *cert, | 1094 CERT_GetConstrainedCertificateNames(const CERTCertificate *cert, |
| 1093 PLArenaPool *arena, | 1095 PLArenaPool *arena, |
| 1094 PRBool includeSubjectCommonName) | 1096 PRBool includeSubjectCommonName) |
| 1095 { | 1097 { |
| 1096 CERTGeneralName *DN; | 1098 CERTGeneralName *DN; |
| 1097 CERTGeneralName *SAN; | 1099 CERTGeneralName *SAN; |
| 1098 PRUint32 numDNSNames = 0; | 1100 PRUint32 numDNSNames = 0; |
| 1099 SECStatus rv; | 1101 SECStatus rv; |
| 1100 | 1102 |
| 1101 if (!arena) { | 1103 if (!arena) { |
| 1102 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1104 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1103 » return NULL; | 1105 return NULL; |
| 1104 } | 1106 } |
| 1105 /* TODO: mark arena */ | 1107 /* TODO: mark arena */ |
| 1106 DN = CERT_NewGeneralName(arena, certDirectoryName); | 1108 DN = CERT_NewGeneralName(arena, certDirectoryName); |
| 1107 if (DN == NULL) { | 1109 if (DN == NULL) { |
| 1108 » goto loser; | 1110 goto loser; |
| 1109 } | 1111 } |
| 1110 rv = CERT_CopyName(arena, &DN->name.directoryName, &cert->subject); | 1112 rv = CERT_CopyName(arena, &DN->name.directoryName, &cert->subject); |
| 1111 if (rv != SECSuccess) { | 1113 if (rv != SECSuccess) { |
| 1112 » goto loser; | 1114 goto loser; |
| 1113 } | 1115 } |
| 1114 rv = SECITEM_CopyItem(arena, &DN->derDirectoryName, &cert->derSubject); | 1116 rv = SECITEM_CopyItem(arena, &DN->derDirectoryName, &cert->derSubject); |
| 1115 if (rv != SECSuccess) { | 1117 if (rv != SECSuccess) { |
| 1116 » goto loser; | 1118 goto loser; |
| 1117 } | 1119 } |
| 1118 /* Extract email addresses from DN, construct CERTGeneralName structs | 1120 /* Extract email addresses from DN, construct CERTGeneralName structs |
| 1119 ** for them, add them to the name list | 1121 ** for them, add them to the name list |
| 1120 */ | 1122 */ |
| 1121 rv = cert_ExtractDNEmailAddrs(DN, arena); | 1123 rv = cert_ExtractDNEmailAddrs(DN, arena); |
| 1122 if (rv != SECSuccess) | 1124 if (rv != SECSuccess) |
| 1123 goto loser; | 1125 goto loser; |
| 1124 | 1126 |
| 1125 /* Now extract any GeneralNames from the subject name names extension. */ | 1127 /* Now extract any GeneralNames from the subject name names extension. */ |
| 1126 SAN = cert_GetSubjectAltNameList(cert, arena); | 1128 SAN = cert_GetSubjectAltNameList(cert, arena); |
| 1127 if (SAN) { | 1129 if (SAN) { |
| 1128 » numDNSNames = cert_CountDNSPatterns(SAN); | 1130 numDNSNames = cert_CountDNSPatterns(SAN); |
| 1129 » DN = cert_CombineNamesLists(DN, SAN); | 1131 DN = cert_CombineNamesLists(DN, SAN); |
| 1130 } | 1132 } |
| 1131 if (!numDNSNames && includeSubjectCommonName) { | 1133 if (!numDNSNames && includeSubjectCommonName) { |
| 1132 » char *cn = CERT_GetCommonName(&cert->subject); | 1134 char *cn = CERT_GetCommonName(&cert->subject); |
| 1133 » if (cn) { | 1135 if (cn) { |
| 1134 » CERTGeneralName *CN = CERT_NewGeneralName(arena, certDNSName); | 1136 CERTGeneralName *CN = CERT_NewGeneralName(arena, certDNSName); |
| 1135 » if (CN) { | 1137 if (CN) { |
| 1136 » » SECItem cnItem = {siBuffer, NULL, 0}; | 1138 SECItem cnItem = { siBuffer, NULL, 0 }; |
| 1137 » » cnItem.data = (unsigned char *)cn; | 1139 cnItem.data = (unsigned char *)cn; |
| 1138 » » cnItem.len = strlen(cn); | 1140 cnItem.len = strlen(cn); |
| 1139 » » rv = SECITEM_CopyItem(arena, &CN->name.other, &cnItem); | 1141 rv = SECITEM_CopyItem(arena, &CN->name.other, &cnItem); |
| 1140 » » if (rv == SECSuccess) { | 1142 if (rv == SECSuccess) { |
| 1141 » » DN = cert_CombineNamesLists(DN, CN); | 1143 DN = cert_CombineNamesLists(DN, CN); |
| 1142 » } | 1144 } |
| 1143 » } | 1145 } |
| 1144 » PORT_Free(cn); | 1146 PORT_Free(cn); |
| 1145 » } | 1147 } |
| 1146 } | 1148 } |
| 1147 if (rv == SECSuccess) { | 1149 if (rv == SECSuccess) { |
| 1148 » /* TODO: unmark arena */ | 1150 /* TODO: unmark arena */ |
| 1149 » return DN; | 1151 return DN; |
| 1150 } | 1152 } |
| 1151 loser: | 1153 loser: |
| 1152 /* TODO: release arena to mark */ | 1154 /* TODO: release arena to mark */ |
| 1153 return NULL; | 1155 return NULL; |
| 1154 } | 1156 } |
| 1155 | 1157 |
| 1156 /* Returns SECSuccess if name matches constraint per RFC 3280 rules for | 1158 /* Returns SECSuccess if name matches constraint per RFC 3280 rules for |
| 1157 ** URI name constraints. SECFailure otherwise. | 1159 ** URI name constraints. SECFailure otherwise. |
| 1158 ** If the constraint begins with a dot, it is a domain name, otherwise | 1160 ** If the constraint begins with a dot, it is a domain name, otherwise |
| 1159 ** It is a host name. Examples: | 1161 ** It is a host name. Examples: |
| 1160 ** Constraint Name Result | 1162 ** Constraint Name Result |
| 1161 ** ------------ --------------- -------- | 1163 ** ------------ --------------- -------- |
| 1162 ** foo.bar.com foo.bar.com matches | 1164 ** foo.bar.com foo.bar.com matches |
| 1163 ** foo.bar.com FoO.bAr.CoM matches | 1165 ** foo.bar.com FoO.bAr.CoM matches |
| 1164 ** foo.bar.com www.foo.bar.com no match | 1166 ** foo.bar.com www.foo.bar.com no match |
| 1165 ** foo.bar.com nofoo.bar.com no match | 1167 ** foo.bar.com nofoo.bar.com no match |
| 1166 ** .foo.bar.com www.foo.bar.com matches | 1168 ** .foo.bar.com www.foo.bar.com matches |
| 1167 ** .foo.bar.com nofoo.bar.com no match | 1169 ** .foo.bar.com nofoo.bar.com no match |
| 1168 ** .foo.bar.com foo.bar.com no match | 1170 ** .foo.bar.com foo.bar.com no match |
| 1169 ** .foo.bar.com www..foo.bar.com no match | 1171 ** .foo.bar.com www..foo.bar.com no match |
| 1170 */ | 1172 */ |
| 1171 static SECStatus | 1173 static SECStatus |
| 1172 compareURIN2C(const SECItem *name, const SECItem *constraint) | 1174 compareURIN2C(const SECItem *name, const SECItem *constraint) |
| 1173 { | 1175 { |
| 1174 int offset; | 1176 int offset; |
| 1175 /* The spec is silent on intepreting zero-length constraints. | 1177 /* The spec is silent on intepreting zero-length constraints. |
| 1176 ** We interpret them as matching no URI names. | 1178 ** We interpret them as matching no URI names. |
| 1177 */ | 1179 */ |
| 1178 if (!constraint->len) | 1180 if (!constraint->len) |
| 1179 return SECFailure; | 1181 return SECFailure; |
| 1180 if (constraint->data[0] != '.') { | 1182 if (constraint->data[0] != '.') { |
| 1181 » /* constraint is a host name. */ | 1183 /* constraint is a host name. */ |
| 1182 » if (name->len != constraint->len || | 1184 if (name->len != constraint->len || |
| 1183 » PL_strncasecmp((char *)name->data, | 1185 PL_strncasecmp((char *)name->data, (char *)constraint->data, |
| 1184 » » » (char *)constraint->data, constraint->len)) | 1186 constraint->len)) |
| 1185 » return SECFailure; | 1187 return SECFailure; |
| 1186 » return SECSuccess; | 1188 return SECSuccess; |
| 1187 } | 1189 } |
| 1188 /* constraint is a domain name. */ | 1190 /* constraint is a domain name. */ |
| 1189 if (name->len < constraint->len) | 1191 if (name->len < constraint->len) |
| 1190 return SECFailure; | 1192 return SECFailure; |
| 1191 offset = name->len - constraint->len; | 1193 offset = name->len - constraint->len; |
| 1192 if (PL_strncasecmp((char *)(name->data + offset), | 1194 if (PL_strncasecmp((char *)(name->data + offset), (char *)constraint->data, |
| 1193 » » (char *)constraint->data, constraint->len)) | 1195 constraint->len)) |
| 1194 return SECFailure; | 1196 return SECFailure; |
| 1195 if (!offset || | 1197 if (!offset || |
| 1196 (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1) | 1198 (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1) |
| 1197 » return SECSuccess; | 1199 return SECSuccess; |
| 1198 return SECFailure; | 1200 return SECFailure; |
| 1199 } | 1201 } |
| 1200 | 1202 |
| 1201 /* for DNSname constraints, RFC 3280 says, (section 4.2.1.11, page 38) | 1203 /* for DNSname constraints, RFC 3280 says, (section 4.2.1.11, page 38) |
| 1202 ** | 1204 ** |
| 1203 ** DNS name restrictions are expressed as foo.bar.com. Any DNS name | 1205 ** DNS name restrictions are expressed as foo.bar.com. Any DNS name |
| 1204 ** that can be constructed by simply adding to the left hand side of the | 1206 ** that can be constructed by simply adding to the left hand side of the |
| 1205 ** name satisfies the name constraint. For example, www.foo.bar.com | 1207 ** name satisfies the name constraint. For example, www.foo.bar.com |
| 1206 ** would satisfy the constraint but foo1.bar.com would not. | 1208 ** would satisfy the constraint but foo1.bar.com would not. |
| 1207 ** | 1209 ** |
| 1208 ** But NIST's PKITS test suite requires that the constraint be treated | 1210 ** But NIST's PKITS test suite requires that the constraint be treated |
| 1209 ** as a domain name, and requires that any name added to the left hand | 1211 ** as a domain name, and requires that any name added to the left hand |
| 1210 ** side end in a dot ".". Sensible, but not strictly following the RFC. | 1212 ** side end in a dot ".". Sensible, but not strictly following the RFC. |
| 1211 ** | 1213 ** |
| 1212 ** Constraint Name RFC 3280 NIST PKITS | 1214 ** Constraint Name RFC 3280 NIST PKITS |
| 1213 ** ------------ --------------- -------- ---------- | 1215 ** ------------ --------------- -------- ---------- |
| 1214 ** foo.bar.com foo.bar.com matches matches | 1216 ** foo.bar.com foo.bar.com matches matches |
| 1215 ** foo.bar.com FoO.bAr.CoM matches matches | 1217 ** foo.bar.com FoO.bAr.CoM matches matches |
| 1216 ** foo.bar.com www.foo.bar.com matches matches | 1218 ** foo.bar.com www.foo.bar.com matches matches |
| 1217 ** foo.bar.com nofoo.bar.com MATCHES NO MATCH | 1219 ** foo.bar.com nofoo.bar.com MATCHES NO MATCH |
| 1218 ** .foo.bar.com www.foo.bar.com matches matches? disallowed? | 1220 ** .foo.bar.com www.foo.bar.com matches matches? disallowed? |
| 1219 ** .foo.bar.com foo.bar.com no match no match | 1221 ** .foo.bar.com foo.bar.com no match no match |
| 1220 ** .foo.bar.com www..foo.bar.com matches probably not | 1222 ** .foo.bar.com www..foo.bar.com matches probably not |
| 1221 ** | 1223 ** |
| 1222 ** We will try to conform to NIST's PKITS tests, and the unstated | 1224 ** We will try to conform to NIST's PKITS tests, and the unstated |
| 1223 ** rules they imply. | 1225 ** rules they imply. |
| 1224 */ | 1226 */ |
| 1225 static SECStatus | 1227 static SECStatus |
| 1226 compareDNSN2C(const SECItem *name, const SECItem *constraint) | 1228 compareDNSN2C(const SECItem *name, const SECItem *constraint) |
| 1227 { | 1229 { |
| 1228 int offset; | 1230 int offset; |
| 1229 /* The spec is silent on intepreting zero-length constraints. | 1231 /* The spec is silent on intepreting zero-length constraints. |
| 1230 ** We interpret them as matching all DNSnames. | 1232 ** We interpret them as matching all DNSnames. |
| 1231 */ | 1233 */ |
| 1232 if (!constraint->len) | 1234 if (!constraint->len) |
| 1233 return SECSuccess; | 1235 return SECSuccess; |
| 1234 if (name->len < constraint->len) | 1236 if (name->len < constraint->len) |
| 1235 return SECFailure; | 1237 return SECFailure; |
| 1236 offset = name->len - constraint->len; | 1238 offset = name->len - constraint->len; |
| 1237 if (PL_strncasecmp((char *)(name->data + offset), | 1239 if (PL_strncasecmp((char *)(name->data + offset), (char *)constraint->data, |
| 1238 » » (char *)constraint->data, constraint->len)) | 1240 constraint->len)) |
| 1239 return SECFailure; | 1241 return SECFailure; |
| 1240 if (!offset || | 1242 if (!offset || |
| 1241 (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1) | 1243 (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1) |
| 1242 » return SECSuccess; | 1244 return SECSuccess; |
| 1243 return SECFailure; | 1245 return SECFailure; |
| 1244 } | 1246 } |
| 1245 | 1247 |
| 1246 /* Returns SECSuccess if name matches constraint per RFC 3280 rules for | 1248 /* Returns SECSuccess if name matches constraint per RFC 3280 rules for |
| 1247 ** internet email addresses. SECFailure otherwise. | 1249 ** internet email addresses. SECFailure otherwise. |
| 1248 ** If constraint contains a '@' then the two strings much match exactly. | 1250 ** If constraint contains a '@' then the two strings much match exactly. |
| 1249 ** Else if constraint starts with a '.'. then it must match the right-most | 1251 ** Else if constraint starts with a '.'. then it must match the right-most |
| 1250 ** substring of the name, | 1252 ** substring of the name, |
| 1251 ** else constraint string must match entire name after the name's '@'. | 1253 ** else constraint string must match entire name after the name's '@'. |
| 1252 ** Empty constraint string matches all names. All comparisons case insensitive. | 1254 ** Empty constraint string matches all names. All comparisons case insensitive. |
| 1253 */ | 1255 */ |
| 1254 static SECStatus | 1256 static SECStatus |
| 1255 compareRFC822N2C(const SECItem *name, const SECItem *constraint) | 1257 compareRFC822N2C(const SECItem *name, const SECItem *constraint) |
| 1256 { | 1258 { |
| 1257 int offset; | 1259 int offset; |
| 1258 if (!constraint->len) | 1260 if (!constraint->len) |
| 1259 return SECSuccess; | 1261 return SECSuccess; |
| 1260 if (name->len < constraint->len) | 1262 if (name->len < constraint->len) |
| 1261 return SECFailure; | 1263 return SECFailure; |
| 1262 if (constraint->len == 1 && constraint->data[0] == '.') | 1264 if (constraint->len == 1 && constraint->data[0] == '.') |
| 1263 return SECSuccess; | 1265 return SECSuccess; |
| 1264 for (offset = constraint->len - 1; offset >= 0; --offset) { | 1266 for (offset = constraint->len - 1; offset >= 0; --offset) { |
| 1265 » if (constraint->data[offset] == '@') { | 1267 if (constraint->data[offset] == '@') { |
| 1266 » return (name->len == constraint->len && | 1268 return (name->len == constraint->len && |
| 1267 » !PL_strncasecmp((char *)name->data, | 1269 !PL_strncasecmp((char *)name->data, |
| 1268 » » » » (char *)constraint->data, constraint->len)) | 1270 (char *)constraint->data, constraint->len)) |
| 1269 » » ? SECSuccess : SECFailure; | 1271 ? SECSuccess |
| 1270 » } | 1272 : SECFailure; |
| 1273 } |
| 1271 } | 1274 } |
| 1272 offset = name->len - constraint->len; | 1275 offset = name->len - constraint->len; |
| 1273 if (PL_strncasecmp((char *)(name->data + offset), | 1276 if (PL_strncasecmp((char *)(name->data + offset), (char *)constraint->data, |
| 1274 » » (char *)constraint->data, constraint->len)) | 1277 constraint->len)) |
| 1275 return SECFailure; | 1278 return SECFailure; |
| 1276 if (constraint->data[0] == '.') | 1279 if (constraint->data[0] == '.') |
| 1277 return SECSuccess; | 1280 return SECSuccess; |
| 1278 if (offset > 0 && name->data[offset - 1] == '@') | 1281 if (offset > 0 && name->data[offset - 1] == '@') |
| 1279 return SECSuccess; | 1282 return SECSuccess; |
| 1280 return SECFailure; | 1283 return SECFailure; |
| 1281 } | 1284 } |
| 1282 | 1285 |
| 1283 /* name contains either a 4 byte IPv4 address or a 16 byte IPv6 address. | 1286 /* name contains either a 4 byte IPv4 address or a 16 byte IPv6 address. |
| 1284 ** constraint contains an address of the same length, and a subnet mask | 1287 ** constraint contains an address of the same length, and a subnet mask |
| 1285 ** of the same length. Compare name's address to the constraint's | 1288 ** of the same length. Compare name's address to the constraint's |
| 1286 ** address, subject to the mask. | 1289 ** address, subject to the mask. |
| 1287 ** Return SECSuccess if they match, SECFailure if they don't. | 1290 ** Return SECSuccess if they match, SECFailure if they don't. |
| 1288 */ | 1291 */ |
| 1289 static SECStatus | 1292 static SECStatus |
| 1290 compareIPaddrN2C(const SECItem *name, const SECItem *constraint) | 1293 compareIPaddrN2C(const SECItem *name, const SECItem *constraint) |
| 1291 { | 1294 { |
| 1292 int i; | 1295 int i; |
| 1293 if (name->len == 4 && constraint->len == 8) { /* ipv4 addr */ | 1296 if (name->len == 4 && constraint->len == 8) { /* ipv4 addr */ |
| 1294 for (i = 0; i < 4; i++) { | 1297 for (i = 0; i < 4; i++) { |
| 1295 » if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+4]) | 1298 if ((name->data[i] ^ constraint->data[i]) & constraint->data[i + 4]) |
| 1296 » goto loser; | 1299 goto loser; |
| 1297 » } | 1300 } |
| 1298 » return SECSuccess; | 1301 return SECSuccess; |
| 1299 } | 1302 } |
| 1300 if (name->len == 16 && constraint->len == 32) { /* ipv6 addr */ | 1303 if (name->len == 16 && constraint->len == 32) { /* ipv6 addr */ |
| 1301 for (i = 0; i < 16; i++) { | 1304 for (i = 0; i < 16; i++) { |
| 1302 » if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+16]) | 1305 if ((name->data[i] ^ constraint->data[i]) & |
| 1303 » goto loser; | 1306 constraint->data[i + 16]) |
| 1304 » } | 1307 goto loser; |
| 1305 » return SECSuccess; | 1308 } |
| 1309 return SECSuccess; |
| 1306 } | 1310 } |
| 1307 loser: | 1311 loser: |
| 1308 return SECFailure; | 1312 return SECFailure; |
| 1309 } | 1313 } |
| 1310 | 1314 |
| 1311 /* start with a SECItem that points to a URI. Parse it lookingg for | 1315 /* start with a SECItem that points to a URI. Parse it lookingg for |
| 1312 ** a hostname. Modify item->data and item->len to define the hostname, | 1316 ** a hostname. Modify item->data and item->len to define the hostname, |
| 1313 ** but do not modify and data at item->data. | 1317 ** but do not modify and data at item->data. |
| 1314 ** If anything goes wrong, the contents of *item are undefined. | 1318 ** If anything goes wrong, the contents of *item are undefined. |
| 1315 */ | 1319 */ |
| 1316 static SECStatus | 1320 static SECStatus |
| 1317 parseUriHostname(SECItem * item) | 1321 parseUriHostname(SECItem *item) |
| 1318 { | 1322 { |
| 1319 int i; | 1323 int i; |
| 1320 PRBool found = PR_FALSE; | 1324 PRBool found = PR_FALSE; |
| 1321 for (i = 0; (unsigned)(i+2) < item->len; ++i) { | 1325 for (i = 0; (unsigned)(i + 2) < item->len; ++i) { |
| 1322 » if (item->data[i ] == ':' && | 1326 if (item->data[i] == ':' && item->data[i + 1] == '/' && |
| 1323 » item->data[i+1] == '/' && | 1327 item->data[i + 2] == '/') { |
| 1324 » item->data[i+2] == '/') { | 1328 i += 3; |
| 1325 » i += 3; | 1329 item->data += i; |
| 1326 » item->data += i; | 1330 item->len -= i; |
| 1327 » item->len -= i; | 1331 found = PR_TRUE; |
| 1328 » found = PR_TRUE; | 1332 break; |
| 1329 » break; | 1333 } |
| 1330 » } | |
| 1331 } | 1334 } |
| 1332 if (!found) | 1335 if (!found) |
| 1333 return SECFailure; | 1336 return SECFailure; |
| 1334 /* now look for a '/', which is an upper bound in the end of the name */ | 1337 /* now look for a '/', which is an upper bound in the end of the name */ |
| 1335 for (i = 0; (unsigned)i < item->len; ++i) { | 1338 for (i = 0; (unsigned)i < item->len; ++i) { |
| 1336 » if (item->data[i] == '/') { | 1339 if (item->data[i] == '/') { |
| 1337 » item->len = i; | 1340 item->len = i; |
| 1338 » break; | 1341 break; |
| 1339 » } | 1342 } |
| 1340 } | 1343 } |
| 1341 /* now look for a ':', which marks the end of the name */ | 1344 /* now look for a ':', which marks the end of the name */ |
| 1342 for (i = item->len; --i >= 0; ) { | 1345 for (i = item->len; --i >= 0;) { |
| 1343 if (item->data[i] == ':') { | 1346 if (item->data[i] == ':') { |
| 1344 » item->len = i; | 1347 item->len = i; |
| 1345 » break; | 1348 break; |
| 1346 » } | 1349 } |
| 1347 } | 1350 } |
| 1348 /* now look for an '@', which marks the beginning of the hostname */ | 1351 /* now look for an '@', which marks the beginning of the hostname */ |
| 1349 for (i = 0; (unsigned)i < item->len; ++i) { | 1352 for (i = 0; (unsigned)i < item->len; ++i) { |
| 1350 » if (item->data[i] == '@') { | 1353 if (item->data[i] == '@') { |
| 1351 » ++i; | 1354 ++i; |
| 1352 » item->data += i; | 1355 item->data += i; |
| 1353 » item->len -= i; | 1356 item->len -= i; |
| 1354 » break; | 1357 break; |
| 1355 » } | 1358 } |
| 1356 } | 1359 } |
| 1357 return item->len ? SECSuccess : SECFailure; | 1360 return item->len ? SECSuccess : SECFailure; |
| 1358 } | 1361 } |
| 1359 | 1362 |
| 1360 /* This function takes one name, and a list of constraints. | 1363 /* This function takes one name, and a list of constraints. |
| 1361 ** It searches the constraints looking for a match. | 1364 ** It searches the constraints looking for a match. |
| 1362 ** It returns SECSuccess if the name satisfies the constraints, i.e., | 1365 ** It returns SECSuccess if the name satisfies the constraints, i.e., |
| 1363 ** if excluded, then the name does not match any constraint, | 1366 ** if excluded, then the name does not match any constraint, |
| 1364 ** if permitted, then the name matches at least one constraint. | 1367 ** if permitted, then the name matches at least one constraint. |
| 1365 ** It returns SECFailure if the name fails to satisfy the constraints, | 1368 ** It returns SECFailure if the name fails to satisfy the constraints, |
| 1366 ** or if some code fails (e.g. out of memory, or invalid constraint) | 1369 ** or if some code fails (e.g. out of memory, or invalid constraint) |
| 1367 */ | 1370 */ |
| 1368 SECStatus | 1371 SECStatus |
| 1369 cert_CompareNameWithConstraints(const CERTGeneralName *name, | 1372 cert_CompareNameWithConstraints(const CERTGeneralName *name, |
| 1370 » » » » const CERTNameConstraint *constraints, | 1373 const CERTNameConstraint *constraints, |
| 1371 » » » » PRBool excluded) | 1374 PRBool excluded) |
| 1372 { | 1375 { |
| 1373 SECStatus rv = SECSuccess; | 1376 SECStatus rv = SECSuccess; |
| 1374 SECStatus matched = SECFailure; | 1377 SECStatus matched = SECFailure; |
| 1375 const CERTNameConstraint *current; | 1378 const CERTNameConstraint *current; |
| 1376 | 1379 |
| 1377 PORT_Assert(constraints); /* caller should not call with NULL */ | 1380 PORT_Assert(constraints); /* caller should not call with NULL */ |
| 1378 if (!constraints) { | 1381 if (!constraints) { |
| 1379 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1382 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1380 return SECFailure; | 1383 return SECFailure; |
| 1381 } | 1384 } |
| 1382 | 1385 |
| 1383 current = constraints; | 1386 current = constraints; |
| 1384 do { | 1387 do { |
| 1385 » rv = SECSuccess; | 1388 rv = SECSuccess; |
| 1386 » matched = SECFailure; | 1389 matched = SECFailure; |
| 1387 » PORT_Assert(name->type == current->name.type); | 1390 PORT_Assert(name->type == current->name.type); |
| 1388 » switch (name->type) { | 1391 switch (name->type) { |
| 1389 | 1392 |
| 1390 » case certDNSName: | 1393 case certDNSName: |
| 1391 » matched = compareDNSN2C(&name->name.other, | 1394 matched = |
| 1392 » ¤t->name.name.other); | 1395 compareDNSN2C(&name->name.other, ¤t->name.name.other); |
| 1393 » break; | 1396 break; |
| 1394 | 1397 |
| 1395 » case certRFC822Name: | 1398 case certRFC822Name: |
| 1396 » matched = compareRFC822N2C(&name->name.other, | 1399 matched = compareRFC822N2C(&name->name.other, |
| 1397 » ¤t->name.name.other); | 1400 ¤t->name.name.other); |
| 1398 » break; | 1401 break; |
| 1399 | 1402 |
| 1400 » case certURI: | 1403 case certURI: { |
| 1401 » { | 1404 /* make a modifiable copy of the URI SECItem. */ |
| 1402 » » /* make a modifiable copy of the URI SECItem. */ | 1405 SECItem uri = name->name.other; |
| 1403 » » SECItem uri = name->name.other; | 1406 /* find the hostname in the URI */ |
| 1404 » » /* find the hostname in the URI */ | 1407 rv = parseUriHostname(&uri); |
| 1405 » » rv = parseUriHostname(&uri); | 1408 if (rv == SECSuccess) { |
| 1406 » » if (rv == SECSuccess) { | 1409 /* does our hostname meet the constraint? */ |
| 1407 » » /* does our hostname meet the constraint? */ | 1410 matched = compareURIN2C(&uri, ¤t->name.name.other); |
| 1408 » » matched = compareURIN2C(&uri, ¤t->name.name.other); | 1411 } |
| 1409 » » } | 1412 } break; |
| 1410 » } | |
| 1411 » break; | |
| 1412 | 1413 |
| 1413 » case certDirectoryName: | 1414 case certDirectoryName: |
| 1414 » /* Determine if the constraint directory name is a "prefix" | 1415 /* Determine if the constraint directory name is a "prefix" |
| 1415 » ** for the directory name being tested. | 1416 ** for the directory name being tested. |
| 1416 » */ | 1417 */ |
| 1417 » { | 1418 { |
| 1418 » /* status defaults to SECEqual, so that a constraint with | 1419 /* status defaults to SECEqual, so that a constraint with |
| 1419 » ** no AVAs will be a wildcard, matching all directory names. | 1420 ** no AVAs will be a wildcard, matching all directory names. |
| 1420 » */ | 1421 */ |
| 1421 » SECComparison status = SECEqual; | 1422 SECComparison status = SECEqual; |
| 1422 » const CERTRDN **cRDNs = | 1423 const CERTRDN **cRDNs = |
| 1423 » » (const CERTRDN **)current->name.name.directoryName.rdns; | 1424 (const CERTRDN **)current->name.name.directoryName.rdns; |
| 1424 » const CERTRDN **nRDNs = | 1425 const CERTRDN **nRDNs = |
| 1425 » » (const CERTRDN **)name->name.directoryName.rdns; | 1426 (const CERTRDN **)name->name.directoryName.rdns; |
| 1426 » while (cRDNs && *cRDNs && nRDNs && *nRDNs) { | 1427 while (cRDNs && *cRDNs && nRDNs && *nRDNs) { |
| 1427 » » /* loop over name RDNs and constraint RDNs in lock step */ | 1428 /* loop over name RDNs and constraint RDNs in lock step |
| 1428 » » const CERTRDN *cRDN = *cRDNs++; | 1429 */ |
| 1429 » » const CERTRDN *nRDN = *nRDNs++; | 1430 const CERTRDN *cRDN = *cRDNs++; |
| 1430 » » CERTAVA **cAVAs = cRDN->avas; | 1431 const CERTRDN *nRDN = *nRDNs++; |
| 1431 » » while (cAVAs && *cAVAs) { /* loop over constraint AVAs */ | 1432 CERTAVA **cAVAs = cRDN->avas; |
| 1432 » » CERTAVA *cAVA = *cAVAs++; | 1433 while (cAVAs && |
| 1433 » » CERTAVA **nAVAs = nRDN->avas; | 1434 *cAVAs) { /* loop over constraint AVAs */ |
| 1434 » » while (nAVAs && *nAVAs) { /* loop over name AVAs */ | 1435 CERTAVA *cAVA = *cAVAs++; |
| 1435 » » » CERTAVA *nAVA = *nAVAs++; | 1436 CERTAVA **nAVAs = nRDN->avas; |
| 1436 » » » status = CERT_CompareAVA(cAVA, nAVA); | 1437 while (nAVAs && *nAVAs) { /* loop over name AVAs */ |
| 1437 » » » if (status == SECEqual) | 1438 CERTAVA *nAVA = *nAVAs++; |
| 1438 » » » break; | 1439 status = CERT_CompareAVA(cAVA, nAVA); |
| 1439 » » } /* loop over name AVAs */ | 1440 if (status == SECEqual) |
| 1440 » » if (status != SECEqual) | 1441 break; |
| 1441 » » » break; | 1442 } /* loop over name AVAs */ |
| 1442 » » } /* loop over constraint AVAs */ | 1443 if (status != SECEqual) |
| 1443 » » if (status != SECEqual) | 1444 break; |
| 1444 » » break; | 1445 } /* loop over constraint AVAs */ |
| 1445 » } /* loop over name RDNs and constraint RDNs */ | 1446 if (status != SECEqual) |
| 1446 » matched = (status == SECEqual) ? SECSuccess : SECFailure; | 1447 break; |
| 1447 » break; | 1448 } /* loop over name RDNs and constraint RDNs */ |
| 1448 » } | 1449 matched = (status == SECEqual) ? SECSuccess : SECFailure; |
| 1450 break; |
| 1451 } |
| 1449 | 1452 |
| 1450 » case certIPAddress:» /* type 8 */ | 1453 case certIPAddress: /* type 8 */ |
| 1451 » matched = compareIPaddrN2C(&name->name.other, | 1454 matched = compareIPaddrN2C(&name->name.other, |
| 1452 » ¤t->name.name.other); | 1455 ¤t->name.name.other); |
| 1453 » break; | 1456 break; |
| 1454 | 1457 |
| 1455 » /* NSS does not know how to compare these "Other" type names with | 1458 /* NSS does not know how to compare these "Other" type names with |
| 1456 » ** their respective constraints. But it does know how to tell | 1459 ** their respective constraints. But it does know how to tell |
| 1457 » ** if the constraint applies to the type of name (by comparing | 1460 ** if the constraint applies to the type of name (by comparing |
| 1458 » ** the constraint OID to the name OID). NSS makes no use of "Other" | 1461 ** the constraint OID to the name OID). NSS makes no use of "Other" |
| 1459 » ** type names at all, so NSS errs on the side of leniency for these | 1462 ** type names at all, so NSS errs on the side of leniency for these |
| 1460 » ** types, provided that their OIDs match. So, when an "Other" | 1463 ** types, provided that their OIDs match. So, when an "Other" |
| 1461 » ** name constraint appears in an excluded subtree, it never causes | 1464 ** name constraint appears in an excluded subtree, it never causes |
| 1462 » ** a name to fail. When an "Other" name constraint appears in a | 1465 ** a name to fail. When an "Other" name constraint appears in a |
| 1463 » ** permitted subtree, AND the constraint's OID matches the name's | 1466 ** permitted subtree, AND the constraint's OID matches the name's |
| 1464 » ** OID, then name is treated as if it matches the constraint. | 1467 ** OID, then name is treated as if it matches the constraint. |
| 1465 » */ | 1468 */ |
| 1466 » case certOtherName:» /* type 1 */ | 1469 case certOtherName: /* type 1 */ |
| 1467 » matched = (!excluded && | 1470 matched = |
| 1468 » » name->type == current->name.type && | 1471 (!excluded && name->type == current->name.type && |
| 1469 » » SECITEM_ItemsAreEqual(&name->name.OthName.oid, | 1472 SECITEM_ItemsAreEqual(&name->name.OthName.oid, |
| 1470 » » » » » ¤t->name.name.OthName.oid)) | 1473 ¤t->name.name.OthName.oid)) |
| 1471 » » ? SECSuccess : SECFailure; | 1474 ? SECSuccess |
| 1472 » break; | 1475 : SECFailure; |
| 1476 break; |
| 1473 | 1477 |
| 1474 » /* NSS does not know how to compare these types of names with their | 1478 /* NSS does not know how to compare these types of names with their |
| 1475 » ** respective constraints. But NSS makes no use of these types of | 1479 ** respective constraints. But NSS makes no use of these types of |
| 1476 » ** names at all, so it errs on the side of leniency for these types. | 1480 ** names at all, so it errs on the side of leniency for these types. |
| 1477 » ** Constraints for these types of names never cause the name to | 1481 ** Constraints for these types of names never cause the name to |
| 1478 » ** fail the constraints test. NSS behaves as if the name matched | 1482 ** fail the constraints test. NSS behaves as if the name matched |
| 1479 » ** for permitted constraints, and did not match for excluded ones. | 1483 ** for permitted constraints, and did not match for excluded ones. |
| 1480 » */ | 1484 */ |
| 1481 » case certX400Address:» /* type 4 */ | 1485 case certX400Address: /* type 4 */ |
| 1482 » case certEDIPartyName: /* type 6 */ | 1486 case certEDIPartyName: /* type 6 */ |
| 1483 » case certRegisterID:» /* type 9 */ | 1487 case certRegisterID: /* type 9 */ |
| 1484 » matched = excluded ? SECFailure : SECSuccess; | 1488 matched = excluded ? SECFailure : SECSuccess; |
| 1485 » break; | 1489 break; |
| 1486 | 1490 |
| 1487 » default: /* non-standard types are not supported */ | 1491 default: /* non-standard types are not supported */ |
| 1488 » rv = SECFailure; | 1492 rv = SECFailure; |
| 1489 » break; | 1493 break; |
| 1490 » } | 1494 } |
| 1491 » if (matched == SECSuccess || rv != SECSuccess) | 1495 if (matched == SECSuccess || rv != SECSuccess) |
| 1492 » break; | 1496 break; |
| 1493 » current = CERT_GetNextNameConstraint((CERTNameConstraint*)current); | 1497 current = CERT_GetNextNameConstraint((CERTNameConstraint *)current); |
| 1494 } while (current != constraints); | 1498 } while (current != constraints); |
| 1495 if (rv == SECSuccess) { | 1499 if (rv == SECSuccess) { |
| 1496 if (matched == SECSuccess) | 1500 if (matched == SECSuccess) |
| 1497 » rv = excluded ? SECFailure : SECSuccess; | 1501 rv = excluded ? SECFailure : SECSuccess; |
| 1498 » else | 1502 else |
| 1499 » rv = excluded ? SECSuccess : SECFailure; | 1503 rv = excluded ? SECSuccess : SECFailure; |
| 1500 » return rv; | 1504 return rv; |
| 1501 } | 1505 } |
| 1502 | 1506 |
| 1503 return SECFailure; | 1507 return SECFailure; |
| 1504 } | 1508 } |
| 1505 | 1509 |
| 1506 /* Add and link a CERTGeneralName to a CERTNameConstraint list. Most | 1510 /* Add and link a CERTGeneralName to a CERTNameConstraint list. Most |
| 1507 ** likely the CERTNameConstraint passed in is either the permitted | 1511 ** likely the CERTNameConstraint passed in is either the permitted |
| 1508 ** list or the excluded list of a CERTNameConstraints. | 1512 ** list or the excluded list of a CERTNameConstraints. |
| 1509 */ | 1513 */ |
| 1510 SECStatus | 1514 SECStatus |
| 1511 CERT_AddNameConstraintByGeneralName(PLArenaPool *arena, | 1515 CERT_AddNameConstraintByGeneralName(PLArenaPool *arena, |
| 1512 CERTNameConstraint **constraints, | 1516 CERTNameConstraint **constraints, |
| 1513 CERTGeneralName *name) | 1517 CERTGeneralName *name) |
| 1514 { | 1518 { |
| 1515 SECStatus rv; | 1519 SECStatus rv; |
| 1516 CERTNameConstraint *current = NULL; | 1520 CERTNameConstraint *current = NULL; |
| 1517 CERTNameConstraint *first = *constraints; | 1521 CERTNameConstraint *first = *constraints; |
| 1518 void *mark = NULL; | 1522 void *mark = NULL; |
| 1519 | 1523 |
| 1520 mark = PORT_ArenaMark(arena); | 1524 mark = PORT_ArenaMark(arena); |
| 1521 | 1525 |
| 1522 current = PORT_ArenaZNew(arena, CERTNameConstraint); | 1526 current = PORT_ArenaZNew(arena, CERTNameConstraint); |
| 1523 if (current == NULL) { | 1527 if (current == NULL) { |
| 1524 rv = SECFailure; | 1528 rv = SECFailure; |
| 1525 goto done; | 1529 goto done; |
| 1526 } | 1530 } |
| 1527 | 1531 |
| 1528 rv = cert_CopyOneGeneralName(arena, ¤t->name, name); | 1532 rv = cert_CopyOneGeneralName(arena, ¤t->name, name); |
| 1529 if (rv != SECSuccess) { | 1533 if (rv != SECSuccess) { |
| 1530 goto done; | 1534 goto done; |
| 1531 } | 1535 } |
| 1532 | 1536 |
| 1533 current->name.l.prev = current->name.l.next = &(current->name.l); | 1537 current->name.l.prev = current->name.l.next = &(current->name.l); |
| 1534 | 1538 |
| 1535 if (first == NULL) { | 1539 if (first == NULL) { |
| 1536 *constraints = current; | 1540 *constraints = current; |
| 1537 PR_INIT_CLIST(¤t->l); | 1541 PR_INIT_CLIST(¤t->l); |
| 1538 } else { | 1542 } else { |
| 1539 PR_INSERT_BEFORE(¤t->l, &first->l); | 1543 PR_INSERT_BEFORE(¤t->l, &first->l); |
| 1540 } | 1544 } |
| 1541 | 1545 |
| 1542 done: | 1546 done: |
| 1543 if (rv == SECFailure) { | 1547 if (rv == SECFailure) { |
| 1544 PORT_ArenaRelease(arena, mark); | 1548 PORT_ArenaRelease(arena, mark); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1562 * | 1566 * |
| 1563 * Entities subject to name constraints are identified by subject name | 1567 * Entities subject to name constraints are identified by subject name |
| 1564 * so that we can cover all certificates for that entity, including, e.g., | 1568 * so that we can cover all certificates for that entity, including, e.g., |
| 1565 * cross-certificates. We use subject rather than public key because | 1569 * cross-certificates. We use subject rather than public key because |
| 1566 * calling methods often have easy access to that field (vs., say, a key ID), | 1570 * calling methods often have easy access to that field (vs., say, a key ID), |
| 1567 * and in practice, subject names and public keys are usually in one-to-one | 1571 * and in practice, subject names and public keys are usually in one-to-one |
| 1568 * correspondence anyway. | 1572 * correspondence anyway. |
| 1569 * | 1573 * |
| 1570 */ | 1574 */ |
| 1571 | 1575 |
| 1572 #define STRING_TO_SECITEM(str) \ | 1576 #define STRING_TO_SECITEM(str) \ |
| 1573 { siBuffer, (unsigned char*) str, sizeof(str) - 1 } | 1577 { \ |
| 1578 siBuffer, (unsigned char *)str, sizeof(str) - 1 \ |
| 1579 } |
| 1574 | 1580 |
| 1575 #define NAME_CONSTRAINTS_ENTRY(CA) \ | 1581 #define NAME_CONSTRAINTS_ENTRY(CA) \ |
| 1576 { \ | 1582 { \ |
| 1577 STRING_TO_SECITEM(CA ## _SUBJECT_DN), \ | 1583 STRING_TO_SECITEM(CA##_SUBJECT_DN), \ |
| 1578 STRING_TO_SECITEM(CA ## _NAME_CONSTRAINTS) \ | 1584 STRING_TO_SECITEM(CA##_NAME_CONSTRAINTS) \ |
| 1579 } | 1585 } |
| 1580 | 1586 |
| 1581 /* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */ | 1587 /* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */ |
| 1582 | 1588 |
| 1583 #define ANSSI_SUBJECT_DN \ | 1589 /* clang-format off */ |
| 1584 "\x30\x81\x85" \ | |
| 1585 "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \ | |
| 1586 "\x31\x0F\x30\x0D\x06\x03\x55\x04\x08\x13\x06" "France" /* ST */ \ | |
| 1587 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" "Paris" /* L */ \ | |
| 1588 "\x31\x10\x30\x0E\x06\x03\x55\x04\x0A\x13\x07" "PM/SGDN" /* O */ \ | |
| 1589 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05" "DCSSI" /* OU */ \ | |
| 1590 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x03\x13\x05" "IGC/A" /* CN */ \ | |
| 1591 "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" \ | |
| 1592 "\x16\x14" "igca@sgdn.pm.gouv.fr" /* emailAddress */ \ | |
| 1593 | 1590 |
| 1594 #define ANSSI_NAME_CONSTRAINTS \ | 1591 #define ANSSI_SUBJECT_DN \ |
| 1595 "\x30\x5D\xA0\x5B" \ | 1592 "\x30\x81\x85" \ |
| 1596 "\x30\x05\x82\x03" ".fr" \ | 1593 "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \ |
| 1597 "\x30\x05\x82\x03" ".gp" \ | 1594 "\x31\x0F\x30\x0D\x06\x03\x55\x04\x08\x13\x06" "France" /* ST */ \ |
| 1598 "\x30\x05\x82\x03" ".gf" \ | 1595 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" "Paris" /* L */ \ |
| 1599 "\x30\x05\x82\x03" ".mq" \ | 1596 "\x31\x10\x30\x0E\x06\x03\x55\x04\x0A\x13\x07" "PM/SGDN" /* O */ \ |
| 1600 "\x30\x05\x82\x03" ".re" \ | 1597 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05" "DCSSI" /* OU */ \ |
| 1601 "\x30\x05\x82\x03" ".yt" \ | 1598 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x03\x13\x05" "IGC/A" /* CN */ \ |
| 1602 "\x30\x05\x82\x03" ".pm" \ | 1599 "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" \ |
| 1603 "\x30\x05\x82\x03" ".bl" \ | 1600 "\x16\x14" "igca@sgdn.pm.gouv.fr" /* emailAddress */ \ |
| 1604 "\x30\x05\x82\x03" ".mf" \ | |
| 1605 "\x30\x05\x82\x03" ".wf" \ | |
| 1606 "\x30\x05\x82\x03" ".pf" \ | |
| 1607 "\x30\x05\x82\x03" ".nc" \ | |
| 1608 "\x30\x05\x82\x03" ".tf" \ | |
| 1609 | 1601 |
| 1610 static const SECItem builtInNameConstraints[][2] = { | 1602 #define ANSSI_NAME_CONSTRAINTS \ |
| 1611 NAME_CONSTRAINTS_ENTRY(ANSSI) | 1603 "\x30\x5D\xA0\x5B" \ |
| 1612 }; | 1604 "\x30\x05\x82\x03" ".fr" \ |
| 1605 "\x30\x05\x82\x03" ".gp" \ |
| 1606 "\x30\x05\x82\x03" ".gf" \ |
| 1607 "\x30\x05\x82\x03" ".mq" \ |
| 1608 "\x30\x05\x82\x03" ".re" \ |
| 1609 "\x30\x05\x82\x03" ".yt" \ |
| 1610 "\x30\x05\x82\x03" ".pm" \ |
| 1611 "\x30\x05\x82\x03" ".bl" \ |
| 1612 "\x30\x05\x82\x03" ".mf" \ |
| 1613 "\x30\x05\x82\x03" ".wf" \ |
| 1614 "\x30\x05\x82\x03" ".pf" \ |
| 1615 "\x30\x05\x82\x03" ".nc" \ |
| 1616 "\x30\x05\x82\x03" ".tf" |
| 1617 |
| 1618 /* clang-format on */ |
| 1619 |
| 1620 static const SECItem builtInNameConstraints[][2] = { NAME_CONSTRAINTS_ENTRY( |
| 1621 ANSSI) }; |
| 1613 | 1622 |
| 1614 SECStatus | 1623 SECStatus |
| 1615 CERT_GetImposedNameConstraints(const SECItem *derSubject, | 1624 CERT_GetImposedNameConstraints(const SECItem *derSubject, SECItem *extensions) |
| 1616 SECItem *extensions) | |
| 1617 { | 1625 { |
| 1618 size_t i; | 1626 size_t i; |
| 1619 | 1627 |
| 1620 if (!extensions) { | 1628 if (!extensions) { |
| 1621 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1629 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1622 return SECFailure; | 1630 return SECFailure; |
| 1623 } | 1631 } |
| 1624 | 1632 |
| 1625 for (i = 0; i < PR_ARRAY_SIZE(builtInNameConstraints); ++i) { | 1633 for (i = 0; i < PR_ARRAY_SIZE(builtInNameConstraints); ++i) { |
| 1626 if (SECITEM_ItemsAreEqual(derSubject, &builtInNameConstraints[i][0])) { | 1634 if (SECITEM_ItemsAreEqual(derSubject, &builtInNameConstraints[i][0])) { |
| 1627 return SECITEM_CopyItem(NULL, | 1635 return SECITEM_CopyItem(NULL, extensions, |
| 1628 extensions, | |
| 1629 &builtInNameConstraints[i][1]); | 1636 &builtInNameConstraints[i][1]); |
| 1630 } | 1637 } |
| 1631 } | 1638 } |
| 1632 | 1639 |
| 1633 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); | 1640 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); |
| 1634 return SECFailure; | 1641 return SECFailure; |
| 1635 } | 1642 } |
| 1636 | 1643 |
| 1637 /* | 1644 /* |
| 1638 * Extract the name constraints extension from the CA cert. | 1645 * Extract the name constraints extension from the CA cert. |
| 1639 * If the certificate contains no name constraints extension, but | 1646 * If the certificate contains no name constraints extension, but |
| 1640 * CERT_GetImposedNameConstraints returns a name constraints extension | 1647 * CERT_GetImposedNameConstraints returns a name constraints extension |
| 1641 * for the subject of the certificate, then that extension will be returned. | 1648 * for the subject of the certificate, then that extension will be returned. |
| 1642 */ | 1649 */ |
| 1643 SECStatus | 1650 SECStatus |
| 1644 CERT_FindNameConstraintsExten(PLArenaPool *arena, | 1651 CERT_FindNameConstraintsExten(PLArenaPool *arena, CERTCertificate *cert, |
| 1645 CERTCertificate *cert, | |
| 1646 CERTNameConstraints **constraints) | 1652 CERTNameConstraints **constraints) |
| 1647 { | 1653 { |
| 1648 SECStatus rv = SECSuccess; | 1654 SECStatus rv = SECSuccess; |
| 1649 SECItem constraintsExtension; | 1655 SECItem constraintsExtension; |
| 1650 void *mark = NULL; | 1656 void *mark = NULL; |
| 1651 | 1657 |
| 1652 *constraints = NULL; | 1658 *constraints = NULL; |
| 1653 | 1659 |
| 1654 rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS, | 1660 rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS, |
| 1655 &constraintsExtension); | 1661 &constraintsExtension); |
| 1656 if (rv != SECSuccess) { | 1662 if (rv != SECSuccess) { |
| 1657 if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { | 1663 if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { |
| 1658 return rv; | 1664 return rv; |
| 1659 } | 1665 } |
| 1660 rv = CERT_GetImposedNameConstraints(&cert->derSubject, | 1666 rv = CERT_GetImposedNameConstraints(&cert->derSubject, |
| 1661 &constraintsExtension); | 1667 &constraintsExtension); |
| 1662 if (rv != SECSuccess) { | 1668 if (rv != SECSuccess) { |
| 1663 if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) { | 1669 if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) { |
| 1664 return SECSuccess; | 1670 return SECSuccess; |
| 1665 } | 1671 } |
| 1666 return rv; | 1672 return rv; |
| 1667 } | 1673 } |
| 1668 } | 1674 } |
| 1669 | 1675 |
| 1670 mark = PORT_ArenaMark(arena); | 1676 mark = PORT_ArenaMark(arena); |
| 1671 | 1677 |
| 1672 *constraints = cert_DecodeNameConstraints(arena, &constraintsExtension); | 1678 *constraints = cert_DecodeNameConstraints(arena, &constraintsExtension); |
| 1673 if (*constraints == NULL) { /* decode failed */ | 1679 if (*constraints == NULL) { /* decode failed */ |
| 1674 rv = SECFailure; | 1680 rv = SECFailure; |
| 1675 } | 1681 } |
| 1676 PORT_Free (constraintsExtension.data); | 1682 PORT_Free(constraintsExtension.data); |
| 1677 | 1683 |
| 1678 if (rv == SECFailure) { | 1684 if (rv == SECFailure) { |
| 1679 PORT_ArenaRelease(arena, mark); | 1685 PORT_ArenaRelease(arena, mark); |
| 1680 } else { | 1686 } else { |
| 1681 PORT_ArenaUnmark(arena, mark); | 1687 PORT_ArenaUnmark(arena, mark); |
| 1682 } | 1688 } |
| 1683 | 1689 |
| 1684 return rv; | 1690 return rv; |
| 1685 } | 1691 } |
| 1686 | 1692 |
| 1687 /* Verify name against all the constraints relevant to that type of | 1693 /* Verify name against all the constraints relevant to that type of |
| 1688 ** the name. | 1694 ** the name. |
| 1689 */ | 1695 */ |
| 1690 SECStatus | 1696 SECStatus |
| 1691 CERT_CheckNameSpace(PLArenaPool *arena, | 1697 CERT_CheckNameSpace(PLArenaPool *arena, const CERTNameConstraints *constraints, |
| 1692 const CERTNameConstraints *constraints, | 1698 const CERTGeneralName *currentName) |
| 1693 const CERTGeneralName *currentName) | |
| 1694 { | 1699 { |
| 1695 CERTNameConstraint *matchingConstraints; | 1700 CERTNameConstraint *matchingConstraints; |
| 1696 SECStatus rv = SECSuccess; | 1701 SECStatus rv = SECSuccess; |
| 1697 | 1702 |
| 1698 if (constraints->excluded != NULL) { | 1703 if (constraints->excluded != NULL) { |
| 1699 rv = CERT_GetNameConstraintByType(constraints->excluded, | 1704 rv = CERT_GetNameConstraintByType(constraints->excluded, |
| 1700 currentName->type, | 1705 currentName->type, |
| 1701 &matchingConstraints, arena); | 1706 &matchingConstraints, arena); |
| 1702 if (rv == SECSuccess && matchingConstraints != NULL) { | 1707 if (rv == SECSuccess && matchingConstraints != NULL) { |
| 1703 rv = cert_CompareNameWithConstraints(currentName, | 1708 rv = cert_CompareNameWithConstraints(currentName, |
| 1704 matchingConstraints, | 1709 matchingConstraints, PR_TRUE); |
| 1705 PR_TRUE); | |
| 1706 } | 1710 } |
| 1707 if (rv != SECSuccess) { | 1711 if (rv != SECSuccess) { |
| 1708 return(rv); | 1712 return (rv); |
| 1709 } | |
| 1710 } | |
| 1711 | |
| 1712 if (constraints->permited != NULL) { | |
| 1713 rv = CERT_GetNameConstraintByType(constraints->permited, | |
| 1714 currentName->type, | |
| 1715 &matchingConstraints, arena); | |
| 1716 if (rv == SECSuccess && matchingConstraints != NULL) { | |
| 1717 rv = cert_CompareNameWithConstraints(currentName, | |
| 1718 matchingConstraints, | |
| 1719 PR_FALSE); | |
| 1720 } | |
| 1721 if (rv != SECSuccess) { | |
| 1722 return(rv); | |
| 1723 } | 1713 } |
| 1724 } | 1714 } |
| 1725 | 1715 |
| 1726 return(SECSuccess); | 1716 if (constraints->permited != NULL) { |
| 1717 rv = CERT_GetNameConstraintByType(constraints->permited, |
| 1718 currentName->type, |
| 1719 &matchingConstraints, arena); |
| 1720 if (rv == SECSuccess && matchingConstraints != NULL) { |
| 1721 rv = cert_CompareNameWithConstraints(currentName, |
| 1722 matchingConstraints, PR_FALSE); |
| 1723 } |
| 1724 if (rv != SECSuccess) { |
| 1725 return (rv); |
| 1726 } |
| 1727 } |
| 1728 |
| 1729 return (SECSuccess); |
| 1727 } | 1730 } |
| 1728 | 1731 |
| 1729 /* Extract the name constraints extension from the CA cert. | 1732 /* Extract the name constraints extension from the CA cert. |
| 1730 ** Test each and every name in namesList against all the constraints | 1733 ** Test each and every name in namesList against all the constraints |
| 1731 ** relevant to that type of name. | 1734 ** relevant to that type of name. |
| 1732 ** Returns NULL in pBadCert for success, if all names are acceptable. | 1735 ** Returns NULL in pBadCert for success, if all names are acceptable. |
| 1733 ** If some name is not acceptable, returns a pointer to the cert that | 1736 ** If some name is not acceptable, returns a pointer to the cert that |
| 1734 ** contained that name. | 1737 ** contained that name. |
| 1735 */ | 1738 */ |
| 1736 SECStatus | 1739 SECStatus |
| 1737 CERT_CompareNameSpace(CERTCertificate *cert, | 1740 CERT_CompareNameSpace(CERTCertificate *cert, CERTGeneralName *namesList, |
| 1738 » » CERTGeneralName *namesList, | 1741 CERTCertificate **certsList, PLArenaPool *reqArena, |
| 1739 » » CERTCertificate **certsList, | 1742 CERTCertificate **pBadCert) |
| 1740 » » PLArenaPool *reqArena, | |
| 1741 » » CERTCertificate **pBadCert) | |
| 1742 { | 1743 { |
| 1743 SECStatus rv = SECSuccess; | 1744 SECStatus rv = SECSuccess; |
| 1744 CERTNameConstraints *constraints; | 1745 CERTNameConstraints *constraints; |
| 1745 CERTGeneralName *currentName; | 1746 CERTGeneralName *currentName; |
| 1746 int count = 0; | 1747 int count = 0; |
| 1747 CERTCertificate *badCert = NULL; | 1748 CERTCertificate *badCert = NULL; |
| 1748 | 1749 |
| 1749 /* If no names to check, then no names can be bad. */ | 1750 /* If no names to check, then no names can be bad. */ |
| 1750 if (!namesList) | 1751 if (!namesList) |
| 1751 » goto done; | 1752 goto done; |
| 1752 rv = CERT_FindNameConstraintsExten(reqArena, cert, &constraints); | 1753 rv = CERT_FindNameConstraintsExten(reqArena, cert, &constraints); |
| 1753 if (rv != SECSuccess) { | 1754 if (rv != SECSuccess) { |
| 1754 » count = -1; | 1755 count = -1; |
| 1755 » goto done; | 1756 goto done; |
| 1756 } | 1757 } |
| 1757 | 1758 |
| 1758 currentName = namesList; | 1759 currentName = namesList; |
| 1759 do { | 1760 do { |
| 1760 » if (constraints){ | 1761 if (constraints) { |
| 1761 » rv = CERT_CheckNameSpace(reqArena, constraints, currentName); | 1762 rv = CERT_CheckNameSpace(reqArena, constraints, currentName); |
| 1762 » if (rv != SECSuccess) { | 1763 if (rv != SECSuccess) { |
| 1763 » » break; | 1764 break; |
| 1764 » } | 1765 } |
| 1765 » } | 1766 } |
| 1766 » currentName = CERT_GetNextGeneralName(currentName); | 1767 currentName = CERT_GetNextGeneralName(currentName); |
| 1767 » count ++; | 1768 count++; |
| 1768 } while (currentName != namesList); | 1769 } while (currentName != namesList); |
| 1769 | 1770 |
| 1770 done: | 1771 done: |
| 1771 if (rv != SECSuccess) { | 1772 if (rv != SECSuccess) { |
| 1772 » badCert = (count >= 0) ? certsList[count] : cert; | 1773 badCert = (count >= 0) ? certsList[count] : cert; |
| 1773 } | 1774 } |
| 1774 if (pBadCert) | 1775 if (pBadCert) |
| 1775 » *pBadCert = badCert; | 1776 *pBadCert = badCert; |
| 1776 | 1777 |
| 1777 return rv; | 1778 return rv; |
| 1778 } | 1779 } |
| 1779 | 1780 |
| 1780 #if 0 | 1781 #if 0 |
| 1781 /* not exported from shared libs, not used. Turn on if we ever need it. */ | 1782 /* not exported from shared libs, not used. Turn on if we ever need it. */ |
| 1782 SECStatus | 1783 SECStatus |
| 1783 CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b) | 1784 CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b) |
| 1784 { | 1785 { |
| 1785 CERTGeneralName *currentA; | 1786 CERTGeneralName *currentA; |
| 1786 CERTGeneralName *currentB; | 1787 CERTGeneralName *currentB; |
| 1787 PRBool found; | 1788 PRBool found; |
| 1788 | 1789 |
| 1789 currentA = a; | 1790 currentA = a; |
| 1790 currentB = b; | 1791 currentB = b; |
| 1791 if (a != NULL) { | 1792 if (a != NULL) { |
| 1792 » do { | 1793 » do { |
| 1793 if (currentB == NULL) { | 1794 if (currentB == NULL) { |
| 1794 return SECFailure; | 1795 return SECFailure; |
| 1795 } | 1796 } |
| 1796 currentB = CERT_GetNextGeneralName(currentB); | 1797 currentB = CERT_GetNextGeneralName(currentB); |
| 1797 currentA = CERT_GetNextGeneralName(currentA); | 1798 currentA = CERT_GetNextGeneralName(currentA); |
| 1798 } while (currentA != a); | 1799 } while (currentA != a); |
| 1799 } | 1800 } |
| 1800 if (currentB != b) { | 1801 if (currentB != b) { |
| 1801 return SECFailure; | 1802 return SECFailure; |
| 1802 } | 1803 } |
| 1803 currentA = a; | 1804 currentA = a; |
| 1804 do { | 1805 do { |
| 1805 currentB = b; | 1806 currentB = b; |
| 1806 found = PR_FALSE; | 1807 found = PR_FALSE; |
| 1807 do { | 1808 do { |
| 1808 if (currentB->type == currentA->type) { | 1809 if (currentB->type == currentA->type) { |
| 1809 switch (currentB->type) { | 1810 switch (currentB->type) { |
| 1810 case certDNSName: | 1811 case certDNSName: |
| 1811 case certEDIPartyName: | 1812 case certEDIPartyName: |
| 1812 case certIPAddress: | 1813 case certIPAddress: |
| 1813 case certRegisterID: | 1814 case certRegisterID: |
| 1814 case certRFC822Name: | 1815 case certRFC822Name: |
| 1815 case certX400Address: | 1816 case certX400Address: |
| 1816 case certURI: | 1817 case certURI: |
| 1817 if (SECITEM_CompareItem(¤tA->name.other, | 1818 if (SECITEM_CompareItem(¤tA->name.other, |
| 1818 » » » » » ¤tB->name.other) | 1819 » » » » » ¤tB->name.other) |
| 1819 == SECEqual) { | 1820 == SECEqual) { |
| 1820 found = PR_TRUE; | 1821 found = PR_TRUE; |
| 1821 } | 1822 } |
| 1822 break; | 1823 break; |
| 1823 case certOtherName: | 1824 case certOtherName: |
| 1824 if (SECITEM_CompareItem(¤tA->name.OthName.oid, | 1825 if (SECITEM_CompareItem(¤tA->name.OthName.oid, |
| 1825 » » » » » ¤tB->name.OthName.oid) | 1826 » » » » » ¤tB->name.OthName.oid) |
| 1826 == SECEqual && | 1827 == SECEqual && |
| 1827 SECITEM_CompareItem(¤tA->name.OthName.name, | 1828 SECITEM_CompareItem(¤tA->name.OthName.name, |
| 1828 ¤tB->name.OthName.name) | 1829 ¤tB->name.OthName.name) |
| 1829 == SECEqual) { | 1830 == SECEqual) { |
| 1830 found = PR_TRUE; | 1831 found = PR_TRUE; |
| 1831 } | 1832 } |
| 1832 break; | 1833 break; |
| 1833 case certDirectoryName: | 1834 case certDirectoryName: |
| 1834 if (CERT_CompareName(¤tA->name.directoryName, | 1835 if (CERT_CompareName(¤tA->name.directoryName, |
| 1835 ¤tB->name.directoryName) | 1836 ¤tB->name.directoryName) |
| 1836 == SECEqual) { | 1837 == SECEqual) { |
| 1837 found = PR_TRUE; | 1838 found = PR_TRUE; |
| 1838 } | 1839 } |
| 1839 } | 1840 } |
| 1840 » » | 1841 |
| 1841 } | 1842 } |
| 1842 currentB = CERT_GetNextGeneralName(currentB); | 1843 currentB = CERT_GetNextGeneralName(currentB); |
| 1843 } while (currentB != b && found != PR_TRUE); | 1844 } while (currentB != b && found != PR_TRUE); |
| 1844 if (found != PR_TRUE) { | 1845 if (found != PR_TRUE) { |
| 1845 return SECFailure; | 1846 return SECFailure; |
| 1846 } | 1847 } |
| 1847 currentA = CERT_GetNextGeneralName(currentA); | 1848 currentA = CERT_GetNextGeneralName(currentA); |
| 1848 } while (currentA != a); | 1849 } while (currentA != a); |
| 1849 return SECSuccess; | 1850 return SECSuccess; |
| 1850 } | 1851 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1873 #if 0 | 1874 #if 0 |
| 1874 /* This function is not exported from NSS shared libraries, and is not | 1875 /* This function is not exported from NSS shared libraries, and is not |
| 1875 ** used inside of NSS. | 1876 ** used inside of NSS. |
| 1876 ** XXX it doesn't check for failed allocations. :-( | 1877 ** XXX it doesn't check for failed allocations. :-( |
| 1877 */ | 1878 */ |
| 1878 void * | 1879 void * |
| 1879 CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, | 1880 CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, |
| 1880 CERTGeneralNameType type, | 1881 CERTGeneralNameType type, |
| 1881 PLArenaPool *arena) | 1882 PLArenaPool *arena) |
| 1882 { | 1883 { |
| 1883 CERTName *name = NULL; | 1884 CERTName *name = NULL; |
| 1884 SECItem *item = NULL; | 1885 SECItem *item = NULL; |
| 1885 OtherName *other = NULL; | 1886 OtherName *other = NULL; |
| 1886 OtherName *tmpOther = NULL; | 1887 OtherName *tmpOther = NULL; |
| 1887 void *data; | 1888 void *data; |
| 1888 | 1889 |
| 1889 PZ_Lock(list->lock); | 1890 PZ_Lock(list->lock); |
| 1890 data = CERT_GetGeneralNameByType(list->name, type, PR_FALSE); | 1891 data = CERT_GetGeneralNameByType(list->name, type, PR_FALSE); |
| 1891 if (data != NULL) { | 1892 if (data != NULL) { |
| 1892 switch (type) { | 1893 switch (type) { |
| 1893 case certDNSName: | 1894 case certDNSName: |
| 1894 case certEDIPartyName: | 1895 case certEDIPartyName: |
| 1895 case certIPAddress: | 1896 case certIPAddress: |
| 1896 case certRegisterID: | 1897 case certRegisterID: |
| 1897 case certRFC822Name: | 1898 case certRFC822Name: |
| 1898 case certX400Address: | 1899 case certX400Address: |
| 1899 case certURI: | 1900 case certURI: |
| 1900 if (arena != NULL) { | 1901 if (arena != NULL) { |
| 1901 item = PORT_ArenaNew(arena, SECItem); | 1902 item = PORT_ArenaNew(arena, SECItem); |
| 1902 if (item != NULL) { | 1903 if (item != NULL) { |
| 1903 XXX SECITEM_CopyItem(arena, item, (SECItem *) data); | 1904 XXX SECITEM_CopyItem(arena, item, (SECItem *) data); |
| 1904 } | 1905 } |
| 1905 » } else { | 1906 » } else { |
| 1906 item = SECITEM_DupItem((SECItem *) data); | 1907 item = SECITEM_DupItem((SECItem *) data); |
| 1907 } | 1908 } |
| 1908 PZ_Unlock(list->lock); | 1909 PZ_Unlock(list->lock); |
| 1909 return item; | 1910 return item; |
| 1910 case certOtherName: | 1911 case certOtherName: |
| 1911 other = (OtherName *) data; | 1912 other = (OtherName *) data; |
| 1912 if (arena != NULL) { | 1913 if (arena != NULL) { |
| 1913 tmpOther = PORT_ArenaNew(arena, OtherName); | 1914 tmpOther = PORT_ArenaNew(arena, OtherName); |
| 1914 } else { | 1915 } else { |
| 1915 tmpOther = PORT_New(OtherName); | 1916 tmpOther = PORT_New(OtherName); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1936 } | 1937 } |
| 1937 #endif | 1938 #endif |
| 1938 | 1939 |
| 1939 #if 0 | 1940 #if 0 |
| 1940 /* This function is not exported from NSS shared libraries, and is not | 1941 /* This function is not exported from NSS shared libraries, and is not |
| 1941 ** used inside of NSS. | 1942 ** used inside of NSS. |
| 1942 ** XXX it should NOT be a void function, since it does allocations | 1943 ** XXX it should NOT be a void function, since it does allocations |
| 1943 ** that can fail. | 1944 ** that can fail. |
| 1944 */ | 1945 */ |
| 1945 void | 1946 void |
| 1946 CERT_AddGeneralNameToList(CERTGeneralNameList *list, | 1947 CERT_AddGeneralNameToList(CERTGeneralNameList *list, |
| 1947 CERTGeneralNameType type, | 1948 CERTGeneralNameType type, |
| 1948 void *data, SECItem *oid) | 1949 void *data, SECItem *oid) |
| 1949 { | 1950 { |
| 1950 CERTGeneralName *name; | 1951 CERTGeneralName *name; |
| 1951 | 1952 |
| 1952 if (list != NULL && data != NULL) { | 1953 if (list != NULL && data != NULL) { |
| 1953 PZ_Lock(list->lock); | 1954 PZ_Lock(list->lock); |
| 1954 name = CERT_NewGeneralName(list->arena, type); | 1955 name = CERT_NewGeneralName(list->arena, type); |
| 1955 if (!name) | 1956 if (!name) |
| 1956 goto done; | 1957 goto done; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1976 break; | 1977 break; |
| 1977 } | 1978 } |
| 1978 list->name = cert_CombineNamesLists(list->name, name); | 1979 list->name = cert_CombineNamesLists(list->name, name); |
| 1979 list->len++; | 1980 list->len++; |
| 1980 done: | 1981 done: |
| 1981 PZ_Unlock(list->lock); | 1982 PZ_Unlock(list->lock); |
| 1982 } | 1983 } |
| 1983 return; | 1984 return; |
| 1984 } | 1985 } |
| 1985 #endif | 1986 #endif |
| OLD | NEW |