source: UsbWattMeter/trunk/wolfssl-3.7.0/src/ocsp.c@ 165

Last change on this file since 165 was 164, checked in by coas-nagasima, 8 years ago

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 8.9 KB
Line 
1/* ocsp.c
2 *
3 * Copyright (C) 2006-2015 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL. (formerly known as CyaSSL)
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 /* Name change compatibility layer no longer needs to be included here */
23
24#ifdef HAVE_CONFIG_H
25 #include <config.h>
26#endif
27
28#include <wolfssl/wolfcrypt/settings.h>
29
30#ifndef WOLFCRYPT_ONLY
31#ifdef HAVE_OCSP
32
33#include <wolfssl/error-ssl.h>
34#include <wolfssl/ocsp.h>
35#include <wolfssl/internal.h>
36
37
38int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm)
39{
40 WOLFSSL_ENTER("InitOCSP");
41 XMEMSET(ocsp, 0, sizeof(*ocsp));
42 ocsp->cm = cm;
43 if (InitMutex(&ocsp->ocspLock) != 0)
44 return BAD_MUTEX_E;
45
46 return 0;
47}
48
49
50static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert)
51{
52 WOLFSSL_ENTER("InitOCSP_Entry");
53
54 XMEMSET(ocspe, 0, sizeof(*ocspe));
55 XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE);
56 XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE);
57
58 return 0;
59}
60
61
62static void FreeOCSP_Entry(OCSP_Entry* ocspe)
63{
64 CertStatus* tmp = ocspe->status;
65
66 WOLFSSL_ENTER("FreeOCSP_Entry");
67
68 while (tmp) {
69 CertStatus* next = tmp->next;
70 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_STATUS);
71 tmp = next;
72 }
73}
74
75
76void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic)
77{
78 OCSP_Entry* tmp = ocsp->ocspList;
79
80 WOLFSSL_ENTER("FreeOCSP");
81
82 while (tmp) {
83 OCSP_Entry* next = tmp->next;
84 FreeOCSP_Entry(tmp);
85 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
86 tmp = next;
87 }
88
89 FreeMutex(&ocsp->ocspLock);
90 if (dynamic)
91 XFREE(ocsp, NULL, DYNAMIC_TYPE_OCSP);
92}
93
94
95static int xstat2err(int stat)
96{
97 switch (stat) {
98 case CERT_GOOD:
99 return 0;
100 case CERT_REVOKED:
101 return OCSP_CERT_REVOKED;
102 default:
103 return OCSP_CERT_UNKNOWN;
104 }
105}
106
107
108int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
109{
110 byte* ocspReqBuf = NULL;
111 int ocspReqSz = 2048;
112 byte* ocspRespBuf = NULL;
113 int result = -1;
114 OCSP_Entry* ocspe;
115 CertStatus* certStatus = NULL;
116 const char *url;
117 int urlSz;
118#ifdef WOLFSSL_SMALL_STACK
119 CertStatus* newStatus;
120 OcspRequest* ocspRequest;
121 OcspResponse* ocspResponse;
122#else
123 CertStatus newStatus[1];
124 OcspRequest ocspRequest[1];
125 OcspResponse ocspResponse[1];
126#endif
127
128 WOLFSSL_ENTER("CheckCertOCSP");
129
130 if (LockMutex(&ocsp->ocspLock) != 0) {
131 WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
132 return BAD_MUTEX_E;
133 }
134
135 ocspe = ocsp->ocspList;
136 while (ocspe) {
137 if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0
138 && XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash,
139 SHA_DIGEST_SIZE) == 0)
140 break;
141 else
142 ocspe = ocspe->next;
143 }
144
145 if (ocspe == NULL) {
146 ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry),
147 NULL, DYNAMIC_TYPE_OCSP_ENTRY);
148 if (ocspe != NULL) {
149 InitOCSP_Entry(ocspe, cert);
150 ocspe->next = ocsp->ocspList;
151 ocsp->ocspList = ocspe;
152 }
153 else {
154 UnLockMutex(&ocsp->ocspLock);
155 WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
156 return MEMORY_ERROR;
157 }
158 }
159 else {
160 certStatus = ocspe->status;
161 while (certStatus) {
162 if (certStatus->serialSz == cert->serialSz &&
163 XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0)
164 break;
165 else
166 certStatus = certStatus->next;
167 }
168 }
169
170 if (certStatus != NULL) {
171 if (!ValidateDate(certStatus->thisDate,
172 certStatus->thisDateFormat, BEFORE) ||
173 (certStatus->nextDate[0] == 0) ||
174 !ValidateDate(certStatus->nextDate,
175 certStatus->nextDateFormat, AFTER)) {
176 WOLFSSL_MSG("\tinvalid status date, looking up cert");
177 }
178 else {
179 result = xstat2err(certStatus->status);
180 UnLockMutex(&ocsp->ocspLock);
181 WOLFSSL_LEAVE("CheckCertOCSP", result);
182 return result;
183 }
184 }
185
186 UnLockMutex(&ocsp->ocspLock);
187
188 if (ocsp->cm->ocspUseOverrideURL) {
189 url = ocsp->cm->ocspOverrideURL;
190 if (url != NULL && url[0] != '\0')
191 urlSz = (int)XSTRLEN(url);
192 else
193 return OCSP_NEED_URL;
194 }
195 else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
196 url = (const char *)cert->extAuthInfo;
197 urlSz = cert->extAuthInfoSz;
198 }
199 else {
200 /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
201 return 0;
202 }
203
204 ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
205 if (ocspReqBuf == NULL) {
206 WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
207 return MEMORY_ERROR;
208 }
209
210#ifdef WOLFSSL_SMALL_STACK
211 newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
212 DYNAMIC_TYPE_TMP_BUFFER);
213 ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
214 DYNAMIC_TYPE_TMP_BUFFER);
215 ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
216 DYNAMIC_TYPE_TMP_BUFFER);
217
218 if (newStatus == NULL || ocspRequest == NULL || ocspResponse == NULL) {
219 if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
220 if (ocspRequest) XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
221 if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
222
223 XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
224
225 WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
226 return MEMORY_E;
227 }
228#endif
229
230 InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
231 ocspReqBuf, ocspReqSz);
232 ocspReqSz = EncodeOcspRequest(ocspRequest);
233
234 if (ocsp->cm->ocspIOCb)
235 result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
236 ocspReqBuf, ocspReqSz, &ocspRespBuf);
237
238 if (result >= 0 && ocspRespBuf) {
239 XMEMSET(newStatus, 0, sizeof(CertStatus));
240
241 InitOcspResponse(ocspResponse, newStatus, ocspRespBuf, result);
242 OcspResponseDecode(ocspResponse);
243
244 if (ocspResponse->responseStatus != OCSP_SUCCESSFUL)
245 result = OCSP_LOOKUP_FAIL;
246 else {
247 if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) {
248 result = xstat2err(ocspResponse->status->status);
249
250 if (LockMutex(&ocsp->ocspLock) != 0)
251 result = BAD_MUTEX_E;
252 else {
253 if (certStatus != NULL)
254 /* Replace existing certificate entry with updated */
255 XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
256 else {
257 /* Save new certificate entry */
258 certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus),
259 NULL, DYNAMIC_TYPE_OCSP_STATUS);
260 if (certStatus != NULL) {
261 XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
262 certStatus->next = ocspe->status;
263 ocspe->status = certStatus;
264 ocspe->totalStatus++;
265 }
266 }
267
268 UnLockMutex(&ocsp->ocspLock);
269 }
270 }
271 else
272 result = OCSP_LOOKUP_FAIL;
273 }
274 }
275 else
276 result = OCSP_LOOKUP_FAIL;
277
278 XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
279
280#ifdef WOLFSSL_SMALL_STACK
281 XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
282 XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
283 XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
284#endif
285
286 if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb)
287 ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf);
288
289 WOLFSSL_LEAVE("CheckCertOCSP", result);
290 return result;
291}
292
293
294#else /* HAVE_OCSP */
295
296
297#ifdef _MSC_VER
298 /* 4206 warning for blank file */
299 #pragma warning(disable: 4206)
300#endif
301
302
303#endif /* HAVE_OCSP */
304#endif /* WOLFCRYPT_ONLY */
305
Note: See TracBrowser for help on using the repository browser.