cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Committer:
ashleymills
Date:
Fri Apr 26 16:59:36 2013 +0000
Revision:
1:b211d97b0068
Parent:
0:e979170e02e7
nothing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:e979170e02e7 1 /* ocsp.c
ashleymills 0:e979170e02e7 2 *
ashleymills 0:e979170e02e7 3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
ashleymills 0:e979170e02e7 4 *
ashleymills 0:e979170e02e7 5 * This file is part of CyaSSL.
ashleymills 0:e979170e02e7 6 *
ashleymills 0:e979170e02e7 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:e979170e02e7 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:e979170e02e7 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:e979170e02e7 10 * (at your option) any later version.
ashleymills 0:e979170e02e7 11 *
ashleymills 0:e979170e02e7 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:e979170e02e7 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:e979170e02e7 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:e979170e02e7 15 * GNU General Public License for more details.
ashleymills 0:e979170e02e7 16 *
ashleymills 0:e979170e02e7 17 * You should have received a copy of the GNU General Public License
ashleymills 0:e979170e02e7 18 * along with this program; if not, write to the Free Software
ashleymills 0:e979170e02e7 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:e979170e02e7 20 */
ashleymills 0:e979170e02e7 21
ashleymills 0:e979170e02e7 22 #ifdef HAVE_CONFIG_H
ashleymills 0:e979170e02e7 23 #include <config.h>
ashleymills 0:e979170e02e7 24 #endif
ashleymills 0:e979170e02e7 25
ashleymills 0:e979170e02e7 26 #ifdef HAVE_OCSP
ashleymills 0:e979170e02e7 27
ashleymills 0:e979170e02e7 28 #ifdef EBSNET
ashleymills 0:e979170e02e7 29 #include "rtip.h"
ashleymills 0:e979170e02e7 30 #include "socket.h"
ashleymills 0:e979170e02e7 31 #endif
ashleymills 0:e979170e02e7 32
ashleymills 0:e979170e02e7 33 #include <cyassl/error.h>
ashleymills 0:e979170e02e7 34 #include <cyassl/ocsp.h>
ashleymills 0:e979170e02e7 35 #include <cyassl/internal.h>
ashleymills 0:e979170e02e7 36 #include <ctype.h>
ashleymills 0:e979170e02e7 37
ashleymills 0:e979170e02e7 38 #include <string.h>
ashleymills 0:e979170e02e7 39
ashleymills 0:e979170e02e7 40 #ifndef EBSNET
ashleymills 0:e979170e02e7 41 #include <unistd.h>
ashleymills 0:e979170e02e7 42 #include <netdb.h>
ashleymills 0:e979170e02e7 43 #include <netinet/in.h>
ashleymills 0:e979170e02e7 44 #include <netinet/tcp.h>
ashleymills 0:e979170e02e7 45 #include <arpa/inet.h>
ashleymills 0:e979170e02e7 46 #include <sys/ioctl.h>
ashleymills 0:e979170e02e7 47 #include <sys/time.h>
ashleymills 0:e979170e02e7 48 #include <sys/types.h>
ashleymills 0:e979170e02e7 49 #include <sys/socket.h>
ashleymills 0:e979170e02e7 50 #endif
ashleymills 0:e979170e02e7 51
ashleymills 0:e979170e02e7 52
ashleymills 0:e979170e02e7 53 CYASSL_API int ocsp_test(unsigned char* buf, int sz);
ashleymills 0:e979170e02e7 54 #define CYASSL_OCSP_ENABLE 0x0001 /* Enable OCSP lookups */
ashleymills 0:e979170e02e7 55 #define CYASSL_OCSP_URL_OVERRIDE 0x0002 /* Use the override URL instead of URL
ashleymills 0:e979170e02e7 56 * in certificate */
ashleymills 0:e979170e02e7 57 #define CYASSL_OCSP_NO_NONCE 0x0004 /* Disables the request nonce */
ashleymills 0:e979170e02e7 58
ashleymills 0:e979170e02e7 59 typedef struct sockaddr_in SOCKADDR_IN_T;
ashleymills 0:e979170e02e7 60 #define AF_INET_V AF_INET
ashleymills 0:e979170e02e7 61 #define SOCKET_T unsigned int
ashleymills 0:e979170e02e7 62
ashleymills 0:e979170e02e7 63
ashleymills 0:e979170e02e7 64 int CyaSSL_OCSP_Init(CYASSL_OCSP* ocsp)
ashleymills 0:e979170e02e7 65 {
ashleymills 0:e979170e02e7 66 if (ocsp != NULL) {
ashleymills 0:e979170e02e7 67 XMEMSET(ocsp, 0, sizeof(*ocsp));
ashleymills 0:e979170e02e7 68 ocsp->useNonce = 1;
ashleymills 0:e979170e02e7 69 #ifndef CYASSL_USER_IO
ashleymills 0:e979170e02e7 70 ocsp->CBIOOcsp = EmbedOcspLookup;
ashleymills 0:e979170e02e7 71 ocsp->CBIOOcspRespFree = EmbedOcspRespFree;
ashleymills 0:e979170e02e7 72 #endif
ashleymills 0:e979170e02e7 73 return 0;
ashleymills 0:e979170e02e7 74 }
ashleymills 0:e979170e02e7 75
ashleymills 0:e979170e02e7 76 return -1;
ashleymills 0:e979170e02e7 77 }
ashleymills 0:e979170e02e7 78
ashleymills 0:e979170e02e7 79
ashleymills 0:e979170e02e7 80 static void FreeOCSP_Entry(OCSP_Entry* ocspe)
ashleymills 0:e979170e02e7 81 {
ashleymills 0:e979170e02e7 82 CertStatus* tmp = ocspe->status;
ashleymills 0:e979170e02e7 83
ashleymills 0:e979170e02e7 84 CYASSL_ENTER("FreeOCSP_Entry");
ashleymills 0:e979170e02e7 85
ashleymills 0:e979170e02e7 86 while (tmp) {
ashleymills 0:e979170e02e7 87 CertStatus* next = tmp->next;
ashleymills 0:e979170e02e7 88 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_STATUS);
ashleymills 0:e979170e02e7 89 tmp = next;
ashleymills 0:e979170e02e7 90 }
ashleymills 0:e979170e02e7 91 }
ashleymills 0:e979170e02e7 92
ashleymills 0:e979170e02e7 93
ashleymills 0:e979170e02e7 94 void CyaSSL_OCSP_Cleanup(CYASSL_OCSP* ocsp)
ashleymills 0:e979170e02e7 95 {
ashleymills 0:e979170e02e7 96 OCSP_Entry* tmp = ocsp->ocspList;
ashleymills 0:e979170e02e7 97
ashleymills 0:e979170e02e7 98 ocsp->enabled = 0;
ashleymills 0:e979170e02e7 99 while (tmp) {
ashleymills 0:e979170e02e7 100 OCSP_Entry* next = tmp->next;
ashleymills 0:e979170e02e7 101 FreeOCSP_Entry(tmp);
ashleymills 0:e979170e02e7 102 XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
ashleymills 0:e979170e02e7 103 tmp = next;
ashleymills 0:e979170e02e7 104 }
ashleymills 0:e979170e02e7 105 }
ashleymills 0:e979170e02e7 106
ashleymills 0:e979170e02e7 107
ashleymills 0:e979170e02e7 108 int CyaSSL_OCSP_set_override_url(CYASSL_OCSP* ocsp, const char* url)
ashleymills 0:e979170e02e7 109 {
ashleymills 0:e979170e02e7 110 if (ocsp != NULL) {
ashleymills 0:e979170e02e7 111 int urlSz = (int)XSTRLEN(url);
ashleymills 0:e979170e02e7 112 if (urlSz < (int)sizeof(ocsp->overrideUrl)) {
ashleymills 0:e979170e02e7 113 XSTRNCPY(ocsp->overrideUrl, url, urlSz);
ashleymills 0:e979170e02e7 114 return 1;
ashleymills 0:e979170e02e7 115 }
ashleymills 0:e979170e02e7 116 }
ashleymills 0:e979170e02e7 117
ashleymills 0:e979170e02e7 118 return 0;
ashleymills 0:e979170e02e7 119 }
ashleymills 0:e979170e02e7 120
ashleymills 0:e979170e02e7 121
ashleymills 0:e979170e02e7 122 static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert)
ashleymills 0:e979170e02e7 123 {
ashleymills 0:e979170e02e7 124 CYASSL_ENTER("InitOCSP_Entry");
ashleymills 0:e979170e02e7 125
ashleymills 0:e979170e02e7 126 ocspe->next = NULL;
ashleymills 0:e979170e02e7 127 XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE);
ashleymills 0:e979170e02e7 128 XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE);
ashleymills 0:e979170e02e7 129 ocspe->status = NULL;
ashleymills 0:e979170e02e7 130 ocspe->totalStatus = 0;
ashleymills 0:e979170e02e7 131
ashleymills 0:e979170e02e7 132 return 0;
ashleymills 0:e979170e02e7 133 }
ashleymills 0:e979170e02e7 134
ashleymills 0:e979170e02e7 135
ashleymills 0:e979170e02e7 136 static OCSP_Entry* find_ocsp_entry(CYASSL_OCSP* ocsp, DecodedCert* cert)
ashleymills 0:e979170e02e7 137 {
ashleymills 0:e979170e02e7 138 OCSP_Entry* entry = ocsp->ocspList;
ashleymills 0:e979170e02e7 139
ashleymills 0:e979170e02e7 140 while (entry)
ashleymills 0:e979170e02e7 141 {
ashleymills 0:e979170e02e7 142 if (XMEMCMP(entry->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0
ashleymills 0:e979170e02e7 143 && XMEMCMP(entry->issuerKeyHash, cert->issuerKeyHash,
ashleymills 0:e979170e02e7 144 SHA_DIGEST_SIZE) == 0)
ashleymills 0:e979170e02e7 145 {
ashleymills 0:e979170e02e7 146 CYASSL_MSG("Found OCSP responder");
ashleymills 0:e979170e02e7 147 break;
ashleymills 0:e979170e02e7 148 }
ashleymills 0:e979170e02e7 149 else
ashleymills 0:e979170e02e7 150 {
ashleymills 0:e979170e02e7 151 entry = entry->next;
ashleymills 0:e979170e02e7 152 }
ashleymills 0:e979170e02e7 153 }
ashleymills 0:e979170e02e7 154
ashleymills 0:e979170e02e7 155 if (entry == NULL)
ashleymills 0:e979170e02e7 156 {
ashleymills 0:e979170e02e7 157 CYASSL_MSG("Add a new OCSP entry");
ashleymills 0:e979170e02e7 158 entry = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry),
ashleymills 0:e979170e02e7 159 NULL, DYNAMIC_TYPE_OCSP_ENTRY);
ashleymills 0:e979170e02e7 160 if (entry != NULL)
ashleymills 0:e979170e02e7 161 {
ashleymills 0:e979170e02e7 162 InitOCSP_Entry(entry, cert);
ashleymills 0:e979170e02e7 163 entry->next = ocsp->ocspList;
ashleymills 0:e979170e02e7 164 ocsp->ocspList = entry;
ashleymills 0:e979170e02e7 165 }
ashleymills 0:e979170e02e7 166 }
ashleymills 0:e979170e02e7 167
ashleymills 0:e979170e02e7 168 return entry;
ashleymills 0:e979170e02e7 169 }
ashleymills 0:e979170e02e7 170
ashleymills 0:e979170e02e7 171
ashleymills 0:e979170e02e7 172 static CertStatus* find_cert_status(OCSP_Entry* ocspe, DecodedCert* cert)
ashleymills 0:e979170e02e7 173 {
ashleymills 0:e979170e02e7 174 CertStatus* stat = ocspe->status;
ashleymills 0:e979170e02e7 175
ashleymills 0:e979170e02e7 176 while (stat)
ashleymills 0:e979170e02e7 177 {
ashleymills 0:e979170e02e7 178 if(stat->serialSz == cert->serialSz &&
ashleymills 0:e979170e02e7 179 (XMEMCMP(stat->serial, cert->serial, cert->serialSz) == 0))
ashleymills 0:e979170e02e7 180 {
ashleymills 0:e979170e02e7 181 break;
ashleymills 0:e979170e02e7 182 }
ashleymills 0:e979170e02e7 183 else
ashleymills 0:e979170e02e7 184 {
ashleymills 0:e979170e02e7 185 stat = stat->next;
ashleymills 0:e979170e02e7 186 }
ashleymills 0:e979170e02e7 187 }
ashleymills 0:e979170e02e7 188 if (stat == NULL)
ashleymills 0:e979170e02e7 189 {
ashleymills 0:e979170e02e7 190 stat = (CertStatus*)XMALLOC(sizeof(CertStatus),
ashleymills 0:e979170e02e7 191 NULL, DYNAMIC_TYPE_OCSP_STATUS);
ashleymills 0:e979170e02e7 192 if (stat != NULL)
ashleymills 0:e979170e02e7 193 {
ashleymills 0:e979170e02e7 194 XMEMCPY(stat->serial, cert->serial, cert->serialSz);
ashleymills 0:e979170e02e7 195 stat->serialSz = cert->serialSz;
ashleymills 0:e979170e02e7 196 stat->status = -1;
ashleymills 0:e979170e02e7 197 stat->nextDate[0] = 0;
ashleymills 0:e979170e02e7 198 ocspe->totalStatus++;
ashleymills 0:e979170e02e7 199
ashleymills 0:e979170e02e7 200 stat->next = ocspe->status;
ashleymills 0:e979170e02e7 201 ocspe->status = stat;
ashleymills 0:e979170e02e7 202 }
ashleymills 0:e979170e02e7 203 }
ashleymills 0:e979170e02e7 204
ashleymills 0:e979170e02e7 205 return stat;
ashleymills 0:e979170e02e7 206 }
ashleymills 0:e979170e02e7 207
ashleymills 0:e979170e02e7 208
ashleymills 0:e979170e02e7 209 static int xstat2err(int stat)
ashleymills 0:e979170e02e7 210 {
ashleymills 0:e979170e02e7 211 switch (stat) {
ashleymills 0:e979170e02e7 212 case CERT_GOOD:
ashleymills 0:e979170e02e7 213 return 0;
ashleymills 0:e979170e02e7 214 break;
ashleymills 0:e979170e02e7 215 case CERT_REVOKED:
ashleymills 0:e979170e02e7 216 return OCSP_CERT_REVOKED;
ashleymills 0:e979170e02e7 217 break;
ashleymills 0:e979170e02e7 218 default:
ashleymills 0:e979170e02e7 219 return OCSP_CERT_UNKNOWN;
ashleymills 0:e979170e02e7 220 break;
ashleymills 0:e979170e02e7 221 }
ashleymills 0:e979170e02e7 222 }
ashleymills 0:e979170e02e7 223
ashleymills 0:e979170e02e7 224
ashleymills 0:e979170e02e7 225 int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
ashleymills 0:e979170e02e7 226 {
ashleymills 0:e979170e02e7 227 byte* ocspReqBuf = NULL;
ashleymills 0:e979170e02e7 228 int ocspReqSz = 2048;
ashleymills 0:e979170e02e7 229 byte* ocspRespBuf = NULL;
ashleymills 0:e979170e02e7 230 OcspRequest ocspRequest;
ashleymills 0:e979170e02e7 231 OcspResponse ocspResponse;
ashleymills 0:e979170e02e7 232 int result = 0;
ashleymills 0:e979170e02e7 233 OCSP_Entry* ocspe;
ashleymills 0:e979170e02e7 234 CertStatus* certStatus;
ashleymills 0:e979170e02e7 235 const char *url;
ashleymills 0:e979170e02e7 236 int urlSz;
ashleymills 0:e979170e02e7 237
ashleymills 0:e979170e02e7 238 /* If OCSP lookups are disabled, return success. */
ashleymills 0:e979170e02e7 239 if (!ocsp->enabled) {
ashleymills 0:e979170e02e7 240 CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD");
ashleymills 0:e979170e02e7 241 return 0;
ashleymills 0:e979170e02e7 242 }
ashleymills 0:e979170e02e7 243
ashleymills 0:e979170e02e7 244 ocspe = find_ocsp_entry(ocsp, cert);
ashleymills 0:e979170e02e7 245 if (ocspe == NULL) {
ashleymills 0:e979170e02e7 246 CYASSL_MSG("alloc OCSP entry failed");
ashleymills 0:e979170e02e7 247 return MEMORY_ERROR;
ashleymills 0:e979170e02e7 248 }
ashleymills 0:e979170e02e7 249
ashleymills 0:e979170e02e7 250 certStatus = find_cert_status(ocspe, cert);
ashleymills 0:e979170e02e7 251 if (certStatus == NULL)
ashleymills 0:e979170e02e7 252 {
ashleymills 0:e979170e02e7 253 CYASSL_MSG("alloc OCSP cert status failed");
ashleymills 0:e979170e02e7 254 return MEMORY_ERROR;
ashleymills 0:e979170e02e7 255 }
ashleymills 0:e979170e02e7 256
ashleymills 0:e979170e02e7 257 if (certStatus->status != -1)
ashleymills 0:e979170e02e7 258 {
ashleymills 0:e979170e02e7 259 if (!ValidateDate(certStatus->thisDate,
ashleymills 0:e979170e02e7 260 certStatus->thisDateFormat, BEFORE) ||
ashleymills 0:e979170e02e7 261 (certStatus->nextDate[0] == 0) ||
ashleymills 0:e979170e02e7 262 !ValidateDate(certStatus->nextDate,
ashleymills 0:e979170e02e7 263 certStatus->nextDateFormat, AFTER))
ashleymills 0:e979170e02e7 264 {
ashleymills 0:e979170e02e7 265 CYASSL_MSG("\tinvalid status date, looking up cert");
ashleymills 0:e979170e02e7 266 certStatus->status = -1;
ashleymills 0:e979170e02e7 267 }
ashleymills 0:e979170e02e7 268 else
ashleymills 0:e979170e02e7 269 {
ashleymills 0:e979170e02e7 270 CYASSL_MSG("\tusing cached status");
ashleymills 0:e979170e02e7 271 result = xstat2err(certStatus->status);
ashleymills 0:e979170e02e7 272 return result;
ashleymills 0:e979170e02e7 273 }
ashleymills 0:e979170e02e7 274 }
ashleymills 0:e979170e02e7 275
ashleymills 0:e979170e02e7 276 if (ocsp->useOverrideUrl || cert->extAuthInfo == NULL) {
ashleymills 0:e979170e02e7 277 if (ocsp->overrideUrl != NULL) {
ashleymills 0:e979170e02e7 278 url = ocsp->overrideUrl;
ashleymills 0:e979170e02e7 279 urlSz = (int)XSTRLEN(url);
ashleymills 0:e979170e02e7 280 }
ashleymills 0:e979170e02e7 281 else
ashleymills 0:e979170e02e7 282 return OCSP_NEED_URL;
ashleymills 0:e979170e02e7 283 }
ashleymills 0:e979170e02e7 284 else {
ashleymills 0:e979170e02e7 285 url = (const char *)cert->extAuthInfo;
ashleymills 0:e979170e02e7 286 urlSz = cert->extAuthInfoSz;
ashleymills 0:e979170e02e7 287 }
ashleymills 0:e979170e02e7 288
ashleymills 0:e979170e02e7 289 ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:e979170e02e7 290 if (ocspReqBuf == NULL) {
ashleymills 0:e979170e02e7 291 CYASSL_MSG("\talloc OCSP request buffer failed");
ashleymills 0:e979170e02e7 292 return MEMORY_ERROR;
ashleymills 0:e979170e02e7 293 }
ashleymills 0:e979170e02e7 294 InitOcspRequest(&ocspRequest, cert, ocsp->useNonce, ocspReqBuf, ocspReqSz);
ashleymills 0:e979170e02e7 295 ocspReqSz = EncodeOcspRequest(&ocspRequest);
ashleymills 0:e979170e02e7 296
ashleymills 0:e979170e02e7 297 if (ocsp->CBIOOcsp) {
ashleymills 0:e979170e02e7 298 result = ocsp->CBIOOcsp(ocsp->IOCB_OcspCtx, url, urlSz,
ashleymills 0:e979170e02e7 299 ocspReqBuf, ocspReqSz, &ocspRespBuf);
ashleymills 0:e979170e02e7 300 }
ashleymills 0:e979170e02e7 301
ashleymills 0:e979170e02e7 302 if (result >= 0) {
ashleymills 0:e979170e02e7 303 InitOcspResponse(&ocspResponse, certStatus, ocspRespBuf, result);
ashleymills 0:e979170e02e7 304 OcspResponseDecode(&ocspResponse);
ashleymills 0:e979170e02e7 305
ashleymills 0:e979170e02e7 306 if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
ashleymills 0:e979170e02e7 307 CYASSL_MSG("OCSP Responder failure");
ashleymills 0:e979170e02e7 308 result = OCSP_LOOKUP_FAIL;
ashleymills 0:e979170e02e7 309 } else {
ashleymills 0:e979170e02e7 310 if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0)
ashleymills 0:e979170e02e7 311 {
ashleymills 0:e979170e02e7 312 result = xstat2err(ocspResponse.status->status);
ashleymills 0:e979170e02e7 313 }
ashleymills 0:e979170e02e7 314 else
ashleymills 0:e979170e02e7 315 {
ashleymills 0:e979170e02e7 316 CYASSL_MSG("OCSP Response incorrect for Request");
ashleymills 0:e979170e02e7 317 result = OCSP_LOOKUP_FAIL;
ashleymills 0:e979170e02e7 318 }
ashleymills 0:e979170e02e7 319 }
ashleymills 0:e979170e02e7 320 }
ashleymills 0:e979170e02e7 321 else {
ashleymills 0:e979170e02e7 322 result = OCSP_LOOKUP_FAIL;
ashleymills 0:e979170e02e7 323 }
ashleymills 0:e979170e02e7 324
ashleymills 0:e979170e02e7 325 if (ocspReqBuf != NULL) {
ashleymills 0:e979170e02e7 326 XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:e979170e02e7 327 }
ashleymills 0:e979170e02e7 328 if (ocspRespBuf != NULL && ocsp->CBIOOcspRespFree) {
ashleymills 0:e979170e02e7 329 ocsp->CBIOOcspRespFree(ocsp->IOCB_OcspCtx, ocspRespBuf);
ashleymills 0:e979170e02e7 330 }
ashleymills 0:e979170e02e7 331
ashleymills 0:e979170e02e7 332 return result;
ashleymills 0:e979170e02e7 333 }
ashleymills 0:e979170e02e7 334
ashleymills 0:e979170e02e7 335
ashleymills 0:e979170e02e7 336 #endif /* HAVE_OCSP */
ashleymills 0:e979170e02e7 337