]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2012,2014 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | * | |
23 | * tsaDERUtilities.c - ASN1 templates Time Stamping Authority requests and responses. | |
24 | * see rfc3161.asn1 for ASN.1 and other comments | |
25 | */ | |
26 | ||
27 | #include <libDER/asn1Types.h> | |
28 | #include <libDER/DER_Decode.h> | |
29 | #include <AssertMacros.h> | |
30 | #include <Security/cssmtype.h> | |
31 | #include <stdlib.h> | |
32 | #include "tsaDERUtilities.h" | |
33 | ||
34 | #ifndef DER_MULTIBYTE_TAGS | |
35 | #error We expect DER_MULTIBYTE_TAGS | |
36 | #endif | |
37 | ||
38 | /* PKIStatusInfo */ | |
39 | typedef struct { | |
40 | DERItem status; // INTEGER | |
41 | DERItem statusString; // UTF8_STRING | SEC_ASN1_OPTIONAL | |
42 | DERItem failInfo; // BIT_STRING | SEC_ASN1_OPTIONAL | |
43 | } DERPKIStatusInfo; | |
44 | ||
45 | /* xx */ | |
46 | typedef struct { | |
47 | DERItem statusString; // UTF8_STRING | SEC_ASN1_OPTIONAL | |
48 | } DERPKIStatusStringInner; | |
49 | ||
50 | /* TimeStampResp */ | |
51 | typedef struct | |
52 | { | |
53 | DERItem status; /* PKIStatusInfo */ | |
54 | DERItem timeStampToken; /* TimeStampToken */ | |
55 | } DERTimeStampResp; | |
56 | ||
57 | /* TimeStampResp */ | |
58 | const DERItemSpec DERTimeStampRespItemSpecs[] = | |
59 | { | |
60 | { DER_OFFSET(DERTimeStampResp, status), | |
61 | ASN1_CONSTR_SEQUENCE, DER_DEC_NO_OPTS }, | |
62 | { DER_OFFSET(DERTimeStampResp, timeStampToken), | |
63 | ASN1_CONSTR_SEQUENCE, DER_DEC_NO_OPTS | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER} | |
64 | }; | |
65 | const DERSize DERNumTimeStampRespItemSpecs = sizeof(DERTimeStampRespItemSpecs) / sizeof(DERItemSpec); | |
66 | ||
67 | /* | |
68 | This code is here rather than in libsecurity_smime because | |
69 | libsecurity_smime doesn't know about libDER | |
70 | */ | |
71 | ||
72 | int DERDecodeTimeStampResponse( | |
73 | const CSSM_DATA *contents, | |
74 | CSSM_DATA *derStatus, | |
75 | CSSM_DATA *derTimeStampToken, | |
76 | size_t *numUsedBytes) /* RETURNED */ | |
77 | { | |
78 | DERReturn drtn = DR_ParamErr; | |
79 | DERDecodedInfo decodedPackage; | |
80 | ||
81 | if (contents) | |
82 | { | |
83 | DERItem derContents = {.data = contents->Data, .length = contents->Length }; | |
84 | DERTimeStampResp derResponse = {{0,},{0,}}; | |
85 | DERReturn rx; | |
86 | require_noerr(DERDecodeItem(&derContents, &decodedPackage), badResponse); | |
87 | ||
88 | rx = DERParseSequenceContent(&decodedPackage.content, | |
89 | DERNumTimeStampRespItemSpecs, DERTimeStampRespItemSpecs, | |
90 | &derResponse, 0); | |
91 | if (rx != DR_Success) | |
92 | goto badResponse; | |
93 | /* | |
94 | require_noerr(DERParseSequenceContent(&decodedPackage.content, | |
95 | DERNumTimeStampRespItemSpecs, DERTimeStampRespItemSpecs, | |
96 | &derResponse, 0), badResponse); | |
97 | */ | |
98 | if (derStatus && derResponse.status.data) | |
99 | { | |
100 | derStatus->Data = malloc(derResponse.status.length); | |
101 | derStatus->Length = derResponse.status.length; | |
102 | memcpy(derStatus->Data, derResponse.status.data, derStatus->Length); | |
103 | } | |
104 | if (derTimeStampToken && derResponse.timeStampToken.data) | |
105 | { | |
106 | derTimeStampToken->Data = malloc(derResponse.timeStampToken.length); | |
107 | derTimeStampToken->Length = derResponse.timeStampToken.length; | |
108 | memcpy(derTimeStampToken->Data, derResponse.timeStampToken.data, derTimeStampToken->Length); | |
109 | } | |
110 | } | |
111 | ||
112 | drtn = DR_Success; | |
113 | ||
114 | badResponse: | |
115 | if (numUsedBytes) | |
116 | *numUsedBytes = decodedPackage.content.length + | |
117 | decodedPackage.content.data - contents->Data; | |
118 | ||
119 | return drtn; | |
120 | } | |
121 |