123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /*
- * X.509 v3 Subject Key Usage Extension
- *
- */
- #include "prtypes.h"
- #include "seccomon.h"
- #include "secdert.h"
- #include "secoidt.h"
- #include "secasn1t.h"
- #include "secasn1.h"
- #include "secport.h"
- #include "certt.h"
- #include "genname.h"
- #include "secerr.h"
- SEC_ASN1_MKSUB(SEC_IntegerTemplate)
- SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
- const SEC_ASN1Template CERTAuthKeyIDTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(CERTAuthKeyID, keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
- offsetof(CERTAuthKeyID, authCertSerialNumber),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { 0 }
- };
- SECStatus
- CERT_EncodeAuthKeyID(PLArenaPool *arena, CERTAuthKeyID *value,
- SECItem *encodedValue)
- {
- SECStatus rv = SECFailure;
- PORT_Assert(value);
- PORT_Assert(arena);
- PORT_Assert(value->DERAuthCertIssuer == NULL);
- PORT_Assert(encodedValue);
- do {
- /* If both of the authCertIssuer and the serial number exist, encode
- the name first. Otherwise, it is an error if one exist and the other
- is not.
- */
- if (value->authCertIssuer) {
- if (!value->authCertSerialNumber.data) {
- PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
- break;
- }
- value->DERAuthCertIssuer =
- cert_EncodeGeneralNames(arena, value->authCertIssuer);
- if (!value->DERAuthCertIssuer) {
- PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
- break;
- }
- } else if (value->authCertSerialNumber.data) {
- PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
- break;
- }
- if (SEC_ASN1EncodeItem(arena, encodedValue, value,
- CERTAuthKeyIDTemplate) == NULL)
- break;
- rv = SECSuccess;
- } while (0);
- return (rv);
- }
- CERTAuthKeyID *
- CERT_DecodeAuthKeyID(PLArenaPool *arena, const SECItem *encodedValue)
- {
- CERTAuthKeyID *value = NULL;
- SECStatus rv = SECFailure;
- void *mark;
- SECItem newEncodedValue;
- PORT_Assert(arena);
- do {
- mark = PORT_ArenaMark(arena);
- value = (CERTAuthKeyID *)PORT_ArenaZAlloc(arena, sizeof(*value));
- if (value == NULL)
- break;
- value->DERAuthCertIssuer = NULL;
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
- if (rv != SECSuccess) {
- break;
- }
- rv = SEC_QuickDERDecodeItem(arena, value, CERTAuthKeyIDTemplate,
- &newEncodedValue);
- if (rv != SECSuccess)
- break;
- value->authCertIssuer =
- cert_DecodeGeneralNames(arena, value->DERAuthCertIssuer);
- if (value->authCertIssuer == NULL)
- break;
- /* what if the general name contains other format but not URI ?
- hl
- */
- if ((value->authCertSerialNumber.data && !value->authCertIssuer) ||
- (!value->authCertSerialNumber.data && value->authCertIssuer)) {
- PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
- break;
- }
- } while (0);
- if (rv != SECSuccess) {
- PORT_ArenaRelease(arena, mark);
- return ((CERTAuthKeyID *)NULL);
- }
- PORT_ArenaUnmark(arena, mark);
- return (value);
- }
|