X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_keychain/lib/tsaDERUtilities.c?ds=inline diff --git a/Security/libsecurity_keychain/lib/tsaDERUtilities.c b/Security/libsecurity_keychain/lib/tsaDERUtilities.c new file mode 100644 index 00000000..87cc6df1 --- /dev/null +++ b/Security/libsecurity_keychain/lib/tsaDERUtilities.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2012,2014 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + * + * tsaDERUtilities.c - ASN1 templates Time Stamping Authority requests and responses. + * see rfc3161.asn1 for ASN.1 and other comments + */ + +#include +#include +#include +#include +#include +#include "tsaDERUtilities.h" + +#ifndef DER_MULTIBYTE_TAGS +#error We expect DER_MULTIBYTE_TAGS +#endif + +/* PKIStatusInfo */ +typedef struct { + DERItem status; // INTEGER + DERItem statusString; // UTF8_STRING | SEC_ASN1_OPTIONAL + DERItem failInfo; // BIT_STRING | SEC_ASN1_OPTIONAL +} DERPKIStatusInfo; + +/* xx */ +typedef struct { + DERItem statusString; // UTF8_STRING | SEC_ASN1_OPTIONAL +} DERPKIStatusStringInner; + +/* TimeStampResp */ +typedef struct +{ + DERItem status; /* PKIStatusInfo */ + DERItem timeStampToken; /* TimeStampToken */ +} DERTimeStampResp; + +/* TimeStampResp */ +const DERItemSpec DERTimeStampRespItemSpecs[] = +{ + { DER_OFFSET(DERTimeStampResp, status), + ASN1_CONSTR_SEQUENCE, DER_DEC_NO_OPTS }, + { DER_OFFSET(DERTimeStampResp, timeStampToken), + ASN1_CONSTR_SEQUENCE, DER_DEC_NO_OPTS | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER} +}; +const DERSize DERNumTimeStampRespItemSpecs = sizeof(DERTimeStampRespItemSpecs) / sizeof(DERItemSpec); + +/* + This code is here rather than in libsecurity_smime because + libsecurity_smime doesn't know about libDER +*/ + +int DERDecodeTimeStampResponse( + const CSSM_DATA *contents, + CSSM_DATA *derStatus, + CSSM_DATA *derTimeStampToken, + size_t *numUsedBytes) /* RETURNED */ +{ + DERReturn drtn = DR_ParamErr; + DERDecodedInfo decodedPackage; + + if (contents) + { + DERItem derContents = {.data = contents->Data, .length = contents->Length }; + DERTimeStampResp derResponse = {{0,},{0,}}; + DERReturn rx; + require_noerr(DERDecodeItem(&derContents, &decodedPackage), badResponse); + + rx = DERParseSequenceContent(&decodedPackage.content, + DERNumTimeStampRespItemSpecs, DERTimeStampRespItemSpecs, + &derResponse, 0); + if (rx != DR_Success) + goto badResponse; +/* + require_noerr(DERParseSequenceContent(&decodedPackage.content, + DERNumTimeStampRespItemSpecs, DERTimeStampRespItemSpecs, + &derResponse, 0), badResponse); +*/ + if (derStatus && derResponse.status.data) + { + derStatus->Data = malloc(derResponse.status.length); + derStatus->Length = derResponse.status.length; + memcpy(derStatus->Data, derResponse.status.data, derStatus->Length); + } + if (derTimeStampToken && derResponse.timeStampToken.data) + { + derTimeStampToken->Data = malloc(derResponse.timeStampToken.length); + derTimeStampToken->Length = derResponse.timeStampToken.length; + memcpy(derTimeStampToken->Data, derResponse.timeStampToken.data, derTimeStampToken->Length); + } + } + + drtn = DR_Success; + +badResponse: + if (numUsedBytes) + *numUsedBytes = decodedPackage.content.length + + decodedPackage.content.data - contents->Data; + + return drtn; +} +