PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/ssl.c

https://github.com/andersmalm/cyassl
C | 8294 lines | 7910 code | 303 blank | 81 comment | 342 complexity | 47672171ab4876142cbdb34145c48e6a MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /* ssl.c
  2. *
  3. * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
  4. *
  5. * This file is part of CyaSSL.
  6. *
  7. * CyaSSL 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. * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #ifdef HAVE_ERRNO_H
  25. #include <errno.h>
  26. #endif
  27. #define TRUE 1
  28. #define FALSE 0
  29. #include <cyassl/ssl.h>
  30. #include <cyassl/internal.h>
  31. #include <cyassl/error.h>
  32. #include <cyassl/ctaocrypt/coding.h>
  33. #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
  34. #include <cyassl/openssl/evp.h>
  35. #endif
  36. #ifdef OPENSSL_EXTRA
  37. /* openssl headers begin */
  38. #include <cyassl/openssl/hmac.h>
  39. #include <cyassl/openssl/crypto.h>
  40. #include <cyassl/openssl/des.h>
  41. #include <cyassl/openssl/bn.h>
  42. #include <cyassl/openssl/dh.h>
  43. #include <cyassl/openssl/rsa.h>
  44. #include <cyassl/openssl/pem.h>
  45. /* openssl headers end, cyassl internal headers next */
  46. #include <cyassl/ctaocrypt/hmac.h>
  47. #include <cyassl/ctaocrypt/random.h>
  48. #include <cyassl/ctaocrypt/des3.h>
  49. #include <cyassl/ctaocrypt/md4.h>
  50. #include <cyassl/ctaocrypt/md5.h>
  51. #include <cyassl/ctaocrypt/arc4.h>
  52. #ifdef CYASSL_SHA512
  53. #include <cyassl/ctaocrypt/sha512.h>
  54. #endif
  55. #endif
  56. #ifndef NO_FILESYSTEM
  57. #if !defined(USE_WINDOWS_API) && !defined(NO_CYASSL_DIR) \
  58. && !defined(EBSNET)
  59. #include <dirent.h>
  60. #endif
  61. #ifdef EBSNET
  62. #include "vfapi.h"
  63. #include "vfile.h"
  64. #endif
  65. #endif /* NO_FILESYSTEM */
  66. #ifndef min
  67. static INLINE word32 min(word32 a, word32 b)
  68. {
  69. return a > b ? b : a;
  70. }
  71. #endif /* min */
  72. #ifndef CYASSL_LEANPSK
  73. char* mystrnstr(const char* s1, const char* s2, unsigned int n)
  74. {
  75. unsigned int s2_len = (unsigned int)XSTRLEN(s2);
  76. if (s2_len == 0)
  77. return (char*)s1;
  78. while (n >= s2_len && s1[0]) {
  79. if (s1[0] == s2[0])
  80. if (XMEMCMP(s1, s2, s2_len) == 0)
  81. return (char*)s1;
  82. s1++;
  83. n--;
  84. }
  85. return NULL;
  86. }
  87. #endif
  88. /* prevent multiple mutex initializations */
  89. static volatile int initRefCount = 0;
  90. static CyaSSL_Mutex count_mutex; /* init ref count mutex */
  91. CYASSL_CTX* CyaSSL_CTX_new(CYASSL_METHOD* method)
  92. {
  93. CYASSL_CTX* ctx = NULL;
  94. CYASSL_ENTER("CYASSL_CTX_new");
  95. if (initRefCount == 0)
  96. CyaSSL_Init(); /* user no longer forced to call Init themselves */
  97. if (method == NULL)
  98. return ctx;
  99. ctx = (CYASSL_CTX*) XMALLOC(sizeof(CYASSL_CTX), 0, DYNAMIC_TYPE_CTX);
  100. if (ctx) {
  101. if (InitSSL_Ctx(ctx, method) < 0) {
  102. CYASSL_MSG("Init CTX failed");
  103. CyaSSL_CTX_free(ctx);
  104. ctx = NULL;
  105. }
  106. }
  107. CYASSL_LEAVE("CYASSL_CTX_new", 0);
  108. return ctx;
  109. }
  110. void CyaSSL_CTX_free(CYASSL_CTX* ctx)
  111. {
  112. CYASSL_ENTER("SSL_CTX_free");
  113. if (ctx)
  114. FreeSSL_Ctx(ctx);
  115. CYASSL_LEAVE("SSL_CTX_free", 0);
  116. }
  117. CYASSL* CyaSSL_new(CYASSL_CTX* ctx)
  118. {
  119. CYASSL* ssl = NULL;
  120. CYASSL_ENTER("SSL_new");
  121. if (ctx == NULL)
  122. return ssl;
  123. ssl = (CYASSL*) XMALLOC(sizeof(CYASSL), ctx->heap,DYNAMIC_TYPE_SSL);
  124. if (ssl)
  125. if (InitSSL(ssl, ctx) < 0) {
  126. FreeSSL(ssl);
  127. ssl = 0;
  128. }
  129. CYASSL_LEAVE("SSL_new", 0);
  130. return ssl;
  131. }
  132. void CyaSSL_free(CYASSL* ssl)
  133. {
  134. CYASSL_ENTER("SSL_free");
  135. if (ssl)
  136. FreeSSL(ssl);
  137. CYASSL_LEAVE("SSL_free", 0);
  138. }
  139. #ifndef CYASSL_LEANPSK
  140. int CyaSSL_set_fd(CYASSL* ssl, int fd)
  141. {
  142. CYASSL_ENTER("SSL_set_fd");
  143. ssl->rfd = fd; /* not used directly to allow IO callbacks */
  144. ssl->wfd = fd;
  145. ssl->IOCB_ReadCtx = &ssl->rfd;
  146. ssl->IOCB_WriteCtx = &ssl->wfd;
  147. #ifdef CYASSL_DTLS
  148. if (ssl->options.dtls) {
  149. ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
  150. ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
  151. ssl->buffers.dtlsCtx.fd = fd;
  152. }
  153. #endif
  154. CYASSL_LEAVE("SSL_set_fd", SSL_SUCCESS);
  155. return SSL_SUCCESS;
  156. }
  157. int CyaSSL_get_fd(const CYASSL* ssl)
  158. {
  159. CYASSL_ENTER("SSL_get_fd");
  160. CYASSL_LEAVE("SSL_get_fd", ssl->rfd);
  161. return ssl->rfd;
  162. }
  163. #endif
  164. #ifndef CYASSL_LEANPSK
  165. void CyaSSL_set_using_nonblock(CYASSL* ssl, int nonblock)
  166. {
  167. CYASSL_ENTER("CyaSSL_set_using_nonblock");
  168. ssl->options.usingNonblock = (nonblock != 0);
  169. }
  170. int CyaSSL_get_using_nonblock(CYASSL* ssl)
  171. {
  172. CYASSL_ENTER("CyaSSL_get_using_nonblock");
  173. CYASSL_LEAVE("CyaSSL_get_using_nonblock", ssl->options.usingNonblock);
  174. return ssl->options.usingNonblock;
  175. }
  176. int CyaSSL_dtls(CYASSL* ssl)
  177. {
  178. return ssl->options.dtls;
  179. }
  180. int CyaSSL_dtls_set_peer(CYASSL* ssl, void* peer, unsigned int peerSz)
  181. {
  182. #ifdef CYASSL_DTLS
  183. void* sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
  184. if (sa != NULL) {
  185. XMEMCPY(sa, peer, peerSz);
  186. ssl->buffers.dtlsCtx.peer.sa = sa;
  187. ssl->buffers.dtlsCtx.peer.sz = peerSz;
  188. return SSL_SUCCESS;
  189. }
  190. return SSL_FAILURE;
  191. #else
  192. (void)ssl;
  193. (void)peer;
  194. (void)peerSz;
  195. return SSL_NOT_IMPLEMENTED;
  196. #endif
  197. }
  198. int CyaSSL_dtls_get_peer(CYASSL* ssl, void* peer, unsigned int* peerSz)
  199. {
  200. #ifdef CYASSL_DTLS
  201. if (peer != NULL && peerSz != NULL
  202. && *peerSz >= ssl->buffers.dtlsCtx.peer.sz) {
  203. *peerSz = ssl->buffers.dtlsCtx.peer.sz;
  204. XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
  205. return SSL_SUCCESS;
  206. }
  207. return SSL_FAILURE;
  208. #else
  209. (void)ssl;
  210. (void)peer;
  211. (void)peerSz;
  212. return SSL_NOT_IMPLEMENTED;
  213. #endif
  214. }
  215. #endif /* CYASSL_LEANPSK */
  216. int CyaSSL_negotiate(CYASSL* ssl)
  217. {
  218. int err = SSL_FATAL_ERROR;
  219. CYASSL_ENTER("CyaSSL_negotiate");
  220. #ifndef NO_CYASSL_SERVER
  221. if (ssl->options.side == SERVER_END)
  222. err = CyaSSL_accept(ssl);
  223. #endif
  224. #ifndef NO_CYASSL_CLIENT
  225. if (ssl->options.side == CLIENT_END)
  226. err = CyaSSL_connect(ssl);
  227. #endif
  228. CYASSL_LEAVE("CyaSSL_negotiate", err);
  229. if (err == SSL_SUCCESS)
  230. return 0;
  231. else
  232. return err;
  233. }
  234. #ifndef CYASSL_LEANPSK
  235. /* object size based on build */
  236. int CyaSSL_GetObjectSize(void)
  237. {
  238. #ifdef SHOW_SIZES
  239. printf("sizeof suites = %lu\n", sizeof(Suites));
  240. printf("sizeof ciphers(2) = %lu\n", sizeof(Ciphers));
  241. printf("\tsizeof arc4 = %lu\n", sizeof(Arc4));
  242. printf("\tsizeof aes = %lu\n", sizeof(Aes));
  243. printf("\tsizeof des3 = %lu\n", sizeof(Des3));
  244. printf("\tsizeof rabbit = %lu\n", sizeof(Rabbit));
  245. printf("sizeof cipher specs = %lu\n", sizeof(CipherSpecs));
  246. printf("sizeof keys = %lu\n", sizeof(Keys));
  247. printf("sizeof MD5 = %lu\n", sizeof(Md5));
  248. printf("sizeof SHA = %lu\n", sizeof(Sha));
  249. printf("sizeof SHA256 = %lu\n", sizeof(Sha256));
  250. printf("sizeof Hashes(2) = %lu\n", sizeof(Hashes));
  251. printf("sizeof Buffers = %lu\n", sizeof(Buffers));
  252. printf("sizeof Options = %lu\n", sizeof(Options));
  253. printf("sizeof Arrays = %lu\n", sizeof(Arrays));
  254. printf("sizeof Session = %lu\n", sizeof(CYASSL_SESSION));
  255. printf("sizeof peerKey = %lu\n", sizeof(RsaKey));
  256. printf("sizeof CYASSL_CIPHER = %lu\n", sizeof(CYASSL_CIPHER));
  257. #endif
  258. return sizeof(CYASSL);
  259. }
  260. #endif
  261. /* XXX should be NO_DH */
  262. #ifndef NO_CERTS
  263. /* server Diffie-Hellman parameters */
  264. int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz,
  265. const unsigned char* g, int gSz)
  266. {
  267. byte havePSK = 0;
  268. byte haveRSA = 1;
  269. CYASSL_ENTER("CyaSSL_SetTmpDH");
  270. if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
  271. if (ssl->options.side != SERVER_END)
  272. return SIDE_ERROR;
  273. if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
  274. XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
  275. if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
  276. XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
  277. ssl->buffers.weOwnDH = 1; /* SSL owns now */
  278. ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
  279. DYNAMIC_TYPE_DH);
  280. if (ssl->buffers.serverDH_P.buffer == NULL)
  281. return MEMORY_E;
  282. ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->ctx->heap,
  283. DYNAMIC_TYPE_DH);
  284. if (ssl->buffers.serverDH_G.buffer == NULL) {
  285. XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
  286. return MEMORY_E;
  287. }
  288. ssl->buffers.serverDH_P.length = pSz;
  289. ssl->buffers.serverDH_G.length = gSz;
  290. XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
  291. XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
  292. ssl->options.haveDH = 1;
  293. #ifndef NO_PSK
  294. havePSK = ssl->options.havePSK;
  295. #endif
  296. #ifdef NO_RSA
  297. haveRSA = 0;
  298. #endif
  299. InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
  300. ssl->options.haveNTRU, ssl->options.haveECDSAsig,
  301. ssl->options.haveStaticECC, ssl->options.side);
  302. CYASSL_LEAVE("CyaSSL_SetTmpDH", 0);
  303. return 0;
  304. }
  305. #endif /* !NO_CERTS */
  306. int CyaSSL_write(CYASSL* ssl, const void* data, int sz)
  307. {
  308. int ret;
  309. CYASSL_ENTER("SSL_write()");
  310. #ifdef HAVE_ERRNO_H
  311. errno = 0;
  312. #endif
  313. ret = SendData(ssl, data, sz);
  314. CYASSL_LEAVE("SSL_write()", ret);
  315. if (ret < 0)
  316. return SSL_FATAL_ERROR;
  317. else
  318. return ret;
  319. }
  320. static int CyaSSL_read_internal(CYASSL* ssl, void* data, int sz, int peek)
  321. {
  322. int ret;
  323. CYASSL_ENTER("CyaSSL_read_internal()");
  324. #ifdef HAVE_ERRNO_H
  325. errno = 0;
  326. #endif
  327. ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
  328. CYASSL_LEAVE("CyaSSL_read_internal()", ret);
  329. if (ret < 0)
  330. return SSL_FATAL_ERROR;
  331. else
  332. return ret;
  333. }
  334. int CyaSSL_peek(CYASSL* ssl, void* data, int sz)
  335. {
  336. CYASSL_ENTER("CyaSSL_peek()");
  337. return CyaSSL_read_internal(ssl, data, sz, TRUE);
  338. }
  339. int CyaSSL_read(CYASSL* ssl, void* data, int sz)
  340. {
  341. CYASSL_ENTER("CyaSSL_read()");
  342. return CyaSSL_read_internal(ssl, data, sz, FALSE);
  343. }
  344. #ifdef HAVE_CAVIUM
  345. int CyaSSL_UseCavium(CYASSL* ssl, int devId)
  346. {
  347. if (ssl == NULL)
  348. return BAD_FUNC_ARG;
  349. ssl->devId = devId;
  350. return 0;
  351. }
  352. int CyaSSL_CTX_UseCavium(CYASSL_CTX* ctx, int devId)
  353. {
  354. if (ctx == NULL)
  355. return BAD_FUNC_ARG;
  356. ctx->devId = devId;
  357. return 0;
  358. }
  359. #endif /* HAVE_CAVIUM */
  360. #ifndef CYASSL_LEANPSK
  361. int CyaSSL_send(CYASSL* ssl, const void* data, int sz, int flags)
  362. {
  363. int ret;
  364. int oldFlags = ssl->wflags;
  365. CYASSL_ENTER("CyaSSL_send()");
  366. ssl->wflags = flags;
  367. ret = CyaSSL_write(ssl, data, sz);
  368. ssl->wflags = oldFlags;
  369. CYASSL_LEAVE("CyaSSL_send()", ret);
  370. return ret;
  371. }
  372. int CyaSSL_recv(CYASSL* ssl, void* data, int sz, int flags)
  373. {
  374. int ret;
  375. int oldFlags = ssl->rflags;
  376. CYASSL_ENTER("CyaSSL_recv()");
  377. ssl->rflags = flags;
  378. ret = CyaSSL_read(ssl, data, sz);
  379. ssl->rflags = oldFlags;
  380. CYASSL_LEAVE("CyaSSL_recv()", ret);
  381. return ret;
  382. }
  383. #endif
  384. int CyaSSL_shutdown(CYASSL* ssl)
  385. {
  386. CYASSL_ENTER("SSL_shutdown()");
  387. if (ssl->options.quietShutdown) {
  388. CYASSL_MSG("quiet shutdown, no close notify sent");
  389. return 0;
  390. }
  391. /* try to send close notify, not an error if can't */
  392. if (!ssl->options.isClosed && !ssl->options.connReset &&
  393. !ssl->options.sentNotify) {
  394. ssl->error = SendAlert(ssl, alert_warning, close_notify);
  395. if (ssl->error < 0) {
  396. CYASSL_ERROR(ssl->error);
  397. return SSL_FATAL_ERROR;
  398. }
  399. ssl->options.sentNotify = 1; /* don't send close_notify twice */
  400. }
  401. CYASSL_LEAVE("SSL_shutdown()", ssl->error);
  402. ssl->error = SSL_ERROR_SYSCALL; /* simulate OpenSSL behavior */
  403. return 0;
  404. }
  405. int CyaSSL_get_error(CYASSL* ssl, int ret)
  406. {
  407. CYASSL_ENTER("SSL_get_error");
  408. CYASSL_LEAVE("SSL_get_error", ssl->error);
  409. if (ret > 0)
  410. return SSL_ERROR_NONE;
  411. /* make sure converted types are handled in SetErrorString() too */
  412. if (ssl->error == WANT_READ)
  413. return SSL_ERROR_WANT_READ; /* convert to OpenSSL type */
  414. else if (ssl->error == WANT_WRITE)
  415. return SSL_ERROR_WANT_WRITE; /* convert to OpenSSL type */
  416. else if (ssl->error == ZERO_RETURN)
  417. return SSL_ERROR_ZERO_RETURN; /* convert to OpenSSL type */
  418. return ssl->error;
  419. }
  420. int CyaSSL_want_read(CYASSL* ssl)
  421. {
  422. CYASSL_ENTER("SSL_want_read");
  423. if (ssl->error == WANT_READ)
  424. return 1;
  425. return 0;
  426. }
  427. int CyaSSL_want_write(CYASSL* ssl)
  428. {
  429. CYASSL_ENTER("SSL_want_write");
  430. if (ssl->error == WANT_WRITE)
  431. return 1;
  432. return 0;
  433. }
  434. char* CyaSSL_ERR_error_string(unsigned long errNumber, char* data)
  435. {
  436. static const char* msg = "Please supply a buffer for error string";
  437. CYASSL_ENTER("ERR_error_string");
  438. if (data) {
  439. SetErrorString((int)errNumber, data);
  440. return data;
  441. }
  442. return (char*)msg;
  443. }
  444. void CyaSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
  445. {
  446. CYASSL_ENTER("CyaSSL_ERR_error_string_n");
  447. if (len) CyaSSL_ERR_error_string(e, buf);
  448. }
  449. /* don't free temporary arrays at end of handshake */
  450. void CyaSSL_KeepArrays(CYASSL* ssl)
  451. {
  452. if (ssl)
  453. ssl->options.saveArrays = 1;
  454. }
  455. /* user doesn't need temporary arrays anymore, Free */
  456. void CyaSSL_FreeArrays(CYASSL* ssl)
  457. {
  458. if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
  459. ssl->options.saveArrays = 0;
  460. FreeArrays(ssl, 1);
  461. }
  462. }
  463. #ifndef NO_CERTS
  464. CYASSL_CERT_MANAGER* CyaSSL_CertManagerNew(void)
  465. {
  466. CYASSL_CERT_MANAGER* cm = NULL;
  467. CYASSL_ENTER("CyaSSL_CertManagerNew");
  468. cm = (CYASSL_CERT_MANAGER*) XMALLOC(sizeof(CYASSL_CERT_MANAGER), 0,
  469. DYNAMIC_TYPE_CERT_MANAGER);
  470. if (cm) {
  471. cm->caList = NULL;
  472. cm->heap = NULL;
  473. cm->caCacheCallback = NULL;
  474. cm->crl = NULL;
  475. cm->crlEnabled = 0;
  476. cm->crlCheckAll = 0;
  477. cm->cbMissingCRL = NULL;
  478. if (InitMutex(&cm->caLock) != 0) {
  479. CYASSL_MSG("Bad mutex init");
  480. CyaSSL_CertManagerFree(cm);
  481. return NULL;
  482. }
  483. }
  484. return cm;
  485. }
  486. void CyaSSL_CertManagerFree(CYASSL_CERT_MANAGER* cm)
  487. {
  488. CYASSL_ENTER("CyaSSL_CertManagerFree");
  489. if (cm) {
  490. #ifdef HAVE_CRL
  491. if (cm->crl)
  492. FreeCRL(cm->crl, 1);
  493. #endif
  494. FreeSigners(cm->caList, NULL);
  495. FreeMutex(&cm->caLock);
  496. XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
  497. }
  498. }
  499. #endif /* !NO_CERTS */
  500. #ifndef NO_FILESYSTEM
  501. void CyaSSL_ERR_print_errors_fp(FILE* fp, int err)
  502. {
  503. char data[MAX_ERROR_SZ + 1];
  504. CYASSL_ENTER("CyaSSL_ERR_print_errors_fp");
  505. SetErrorString(err, data);
  506. fprintf(fp, "%s", data);
  507. }
  508. #endif
  509. int CyaSSL_pending(CYASSL* ssl)
  510. {
  511. CYASSL_ENTER("SSL_pending");
  512. return ssl->buffers.clearOutputBuffer.length;
  513. }
  514. #ifndef CYASSL_LEANPSK
  515. /* trun on handshake group messages for context */
  516. int CyaSSL_CTX_set_group_messages(CYASSL_CTX* ctx)
  517. {
  518. if (ctx == NULL)
  519. return BAD_FUNC_ARG;
  520. ctx->groupMessages = 1;
  521. return SSL_SUCCESS;
  522. }
  523. #endif
  524. #ifndef NO_CYASSL_CLIENT
  525. /* connect enough to get peer cert chain */
  526. int CyaSSL_connect_cert(CYASSL* ssl)
  527. {
  528. int ret;
  529. if (ssl == NULL)
  530. return SSL_FAILURE;
  531. ssl->options.certOnly = 1;
  532. ret = CyaSSL_connect(ssl);
  533. ssl->options.certOnly = 0;
  534. return ret;
  535. }
  536. #endif
  537. #ifndef CYASSL_LEANPSK
  538. /* trun on handshake group messages for ssl object */
  539. int CyaSSL_set_group_messages(CYASSL* ssl)
  540. {
  541. if (ssl == NULL)
  542. return BAD_FUNC_ARG;
  543. ssl->options.groupMessages = 1;
  544. return SSL_SUCCESS;
  545. }
  546. int CyaSSL_SetVersion(CYASSL* ssl, int version)
  547. {
  548. byte haveRSA = 1;
  549. byte havePSK = 0;
  550. CYASSL_ENTER("CyaSSL_SetVersion");
  551. if (ssl == NULL) {
  552. CYASSL_MSG("Bad function argument");
  553. return BAD_FUNC_ARG;
  554. }
  555. switch (version) {
  556. #ifndef NO_OLD_TLS
  557. case CYASSL_SSLV3:
  558. ssl->version = MakeSSLv3();
  559. break;
  560. #endif
  561. #ifndef NO_TLS
  562. #ifndef NO_OLD_TLS
  563. case CYASSL_TLSV1:
  564. ssl->version = MakeTLSv1();
  565. break;
  566. case CYASSL_TLSV1_1:
  567. ssl->version = MakeTLSv1_1();
  568. break;
  569. #endif
  570. case CYASSL_TLSV1_2:
  571. ssl->version = MakeTLSv1_2();
  572. break;
  573. #endif
  574. default:
  575. CYASSL_MSG("Bad function argument");
  576. return BAD_FUNC_ARG;
  577. }
  578. #ifdef NO_RSA
  579. haveRSA = 0;
  580. #endif
  581. #ifndef NO_PSK
  582. havePSK = ssl->options.havePSK;
  583. #endif
  584. InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
  585. ssl->options.haveNTRU, ssl->options.haveECDSAsig,
  586. ssl->options.haveStaticECC, ssl->options.side);
  587. return SSL_SUCCESS;
  588. }
  589. #endif
  590. #ifndef NO_CERTS
  591. /* does CA already exist on signer list */
  592. int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash)
  593. {
  594. Signer* signers;
  595. int ret = 0;
  596. if (LockMutex(&cm->caLock) != 0)
  597. return ret;
  598. signers = cm->caList;
  599. while (signers) {
  600. if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
  601. ret = 1;
  602. break;
  603. }
  604. signers = signers->next;
  605. }
  606. UnLockMutex(&cm->caLock);
  607. return ret;
  608. }
  609. /* return CA if found, otherwise NULL */
  610. Signer* GetCA(void* vp, byte* hash)
  611. {
  612. CYASSL_CERT_MANAGER* cm = (CYASSL_CERT_MANAGER*)vp;
  613. Signer* ret = NULL;
  614. Signer* signers;
  615. if (cm == NULL)
  616. return NULL;
  617. signers = cm->caList;
  618. if (LockMutex(&cm->caLock) != 0)
  619. return ret;
  620. while (signers) {
  621. if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
  622. ret = signers;
  623. break;
  624. }
  625. signers = signers->next;
  626. }
  627. UnLockMutex(&cm->caLock);
  628. return ret;
  629. }
  630. /* owns der, internal now uses too */
  631. /* type flag ids from user or from chain received during verify
  632. don't allow chain ones to be added w/o isCA extension */
  633. int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
  634. {
  635. int ret;
  636. DecodedCert cert;
  637. Signer* signer = 0;
  638. CYASSL_MSG("Adding a CA");
  639. InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
  640. ret = ParseCert(&cert, CA_TYPE, verify, cm);
  641. CYASSL_MSG(" Parsed new CA");
  642. if (ret == 0 && cert.isCA == 0 && type != CYASSL_USER_CA) {
  643. CYASSL_MSG(" Can't add as CA if not actually one");
  644. ret = NOT_CA_ERROR;
  645. }
  646. else if (ret == 0 && AlreadySigner(cm, cert.subjectHash)) {
  647. CYASSL_MSG(" Already have this CA, not adding again");
  648. (void)ret;
  649. }
  650. else if (ret == 0) {
  651. /* take over signer parts */
  652. signer = MakeSigner(cm->heap);
  653. if (!signer)
  654. ret = MEMORY_ERROR;
  655. else {
  656. signer->keyOID = cert.keyOID;
  657. signer->publicKey = cert.publicKey;
  658. signer->pubKeySize = cert.pubKeySize;
  659. signer->name = cert.subjectCN;
  660. XMEMCPY(signer->hash, cert.subjectHash, SHA_DIGEST_SIZE);
  661. signer->next = NULL; /* in case lock fails */
  662. cert.publicKey = 0; /* don't free here */
  663. cert.subjectCN = 0;
  664. if (LockMutex(&cm->caLock) == 0) {
  665. signer->next = cm->caList;
  666. cm->caList = signer; /* takes ownership */
  667. UnLockMutex(&cm->caLock);
  668. if (cm->caCacheCallback)
  669. cm->caCacheCallback(der.buffer, (int)der.length, type);
  670. }
  671. else {
  672. CYASSL_MSG(" CA Mutex Lock failed");
  673. ret = BAD_MUTEX_ERROR;
  674. FreeSigners(signer, cm->heap);
  675. }
  676. }
  677. }
  678. CYASSL_MSG(" Freeing Parsed CA");
  679. FreeDecodedCert(&cert);
  680. CYASSL_MSG(" Freeing der CA");
  681. XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CA);
  682. CYASSL_MSG(" OK Freeing der CA");
  683. CYASSL_LEAVE("AddCA", ret);
  684. if (ret == 0) return SSL_SUCCESS;
  685. return ret;
  686. }
  687. #endif /* !NO_CERTS */
  688. #ifndef NO_SESSION_CACHE
  689. /* basic config gives a cache with 33 sessions, adequate for clients and
  690. embedded servers
  691. MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
  692. aren't under heavy load, basically allows 200 new sessions per minute
  693. BIG_SESSION_CACHE yields 20,0027 sessions
  694. HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
  695. allows over 13,000 new sessions per minute or over 200 new sessions per
  696. second
  697. SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
  698. or systems where the default of nearly 3kB is too much RAM, this define
  699. uses less than 500 bytes RAM
  700. */
  701. #ifdef HUGE_SESSION_CACHE
  702. #define SESSIONS_PER_ROW 11
  703. #define SESSION_ROWS 5981
  704. #elif defined(BIG_SESSION_CACHE)
  705. #define SESSIONS_PER_ROW 7
  706. #define SESSION_ROWS 2861
  707. #elif defined(MEDIUM_SESSION_CACHE)
  708. #define SESSIONS_PER_ROW 5
  709. #define SESSION_ROWS 211
  710. #elif defined(SMALL_SESSION_CACHE)
  711. #define SESSIONS_PER_ROW 2
  712. #define SESSION_ROWS 3
  713. #else
  714. #define SESSIONS_PER_ROW 3
  715. #define SESSION_ROWS 11
  716. #endif
  717. typedef struct SessionRow {
  718. int nextIdx; /* where to place next one */
  719. int totalCount; /* sessions ever on this row */
  720. CYASSL_SESSION Sessions[SESSIONS_PER_ROW];
  721. } SessionRow;
  722. static SessionRow SessionCache[SESSION_ROWS];
  723. static CyaSSL_Mutex session_mutex; /* SessionCache mutex */
  724. #endif /* NO_SESSION_CACHE */
  725. int CyaSSL_Init(void)
  726. {
  727. int ret = 0;
  728. CYASSL_ENTER("CyaSSL_Init");
  729. if (initRefCount == 0) {
  730. #ifndef NO_SESSION_CACHE
  731. if (InitMutex(&session_mutex) != 0)
  732. ret = BAD_MUTEX_ERROR;
  733. #endif
  734. if (InitMutex(&count_mutex) != 0)
  735. ret = BAD_MUTEX_ERROR;
  736. }
  737. if (ret == 0) {
  738. LockMutex(&count_mutex);
  739. initRefCount++;
  740. UnLockMutex(&count_mutex);
  741. }
  742. return ret;
  743. }
  744. #ifndef NO_CERTS
  745. /* Remove PEM header/footer, convert to ASN1, store any encrypted data
  746. info->consumed tracks of PEM bytes consumed in case multiple parts */
  747. int PemToDer(const unsigned char* buff, long longSz, int type,
  748. buffer* der, void* heap, EncryptedInfo* info, int* eccKey)
  749. {
  750. char header[PEM_LINE_LEN];
  751. char footer[PEM_LINE_LEN];
  752. char* headerEnd;
  753. char* footerEnd;
  754. char* consumedEnd;
  755. char* bufferEnd = (char*)(buff + longSz);
  756. long neededSz;
  757. int pkcs8 = 0;
  758. int pkcs8Enc = 0;
  759. int dynamicType = 0;
  760. int sz = (int)longSz;
  761. (void)heap;
  762. (void)dynamicType;
  763. if (type == CERT_TYPE || type == CA_TYPE) {
  764. XSTRNCPY(header, "-----BEGIN CERTIFICATE-----", sizeof(header));
  765. XSTRNCPY(footer, "-----END CERTIFICATE-----", sizeof(footer));
  766. dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
  767. DYNAMIC_TYPE_CERT;
  768. } else if (type == DH_PARAM_TYPE) {
  769. XSTRNCPY(header, "-----BEGIN DH PARAMETERS-----", sizeof(header));
  770. XSTRNCPY(footer, "-----END DH PARAMETERS-----", sizeof(footer));
  771. dynamicType = DYNAMIC_TYPE_KEY;
  772. } else if (type == CRL_TYPE) {
  773. XSTRNCPY(header, "-----BEGIN X509 CRL-----", sizeof(header));
  774. XSTRNCPY(footer, "-----END X509 CRL-----", sizeof(footer));
  775. dynamicType = DYNAMIC_TYPE_CRL;
  776. } else {
  777. XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header));
  778. XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----", sizeof(footer));
  779. dynamicType = DYNAMIC_TYPE_KEY;
  780. }
  781. /* find header */
  782. headerEnd = XSTRNSTR((char*)buff, header, sz);
  783. if (!headerEnd && type == PRIVATEKEY_TYPE) { /* may be pkcs8 */
  784. XSTRNCPY(header, "-----BEGIN PRIVATE KEY-----", sizeof(header));
  785. XSTRNCPY(footer, "-----END PRIVATE KEY-----", sizeof(footer));
  786. headerEnd = XSTRNSTR((char*)buff, header, sz);
  787. if (headerEnd)
  788. pkcs8 = 1;
  789. else {
  790. XSTRNCPY(header, "-----BEGIN ENCRYPTED PRIVATE KEY-----",
  791. sizeof(header));
  792. XSTRNCPY(footer, "-----END ENCRYPTED PRIVATE KEY-----",
  793. sizeof(footer));
  794. headerEnd = XSTRNSTR((char*)buff, header, sz);
  795. if (headerEnd) {
  796. pkcs8Enc = 1;
  797. (void)pkcs8Enc; /* only opensslextra will read */
  798. }
  799. }
  800. }
  801. if (!headerEnd && type == PRIVATEKEY_TYPE) { /* may be ecc */
  802. XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----", sizeof(header));
  803. XSTRNCPY(footer, "-----END EC PRIVATE KEY-----", sizeof(footer));
  804. headerEnd = XSTRNSTR((char*)buff, header, sz);
  805. if (headerEnd)
  806. *eccKey = 1;
  807. }
  808. if (!headerEnd && type == PRIVATEKEY_TYPE) { /* may be dsa */
  809. XSTRNCPY(header, "-----BEGIN DSA PRIVATE KEY-----", sizeof(header));
  810. XSTRNCPY(footer, "-----END DSA PRIVATE KEY-----", sizeof(footer));
  811. headerEnd = XSTRNSTR((char*)buff, header, sz);
  812. }
  813. if (!headerEnd) {
  814. CYASSL_MSG("Couldn't find PEM header");
  815. return SSL_NO_PEM_HEADER;
  816. }
  817. headerEnd += XSTRLEN(header);
  818. /* eat end of line */
  819. if (headerEnd[0] == '\n')
  820. headerEnd++;
  821. else if (headerEnd[1] == '\n')
  822. headerEnd += 2;
  823. else
  824. return SSL_BAD_FILE;
  825. #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
  826. {
  827. /* remove encrypted header if there */
  828. char encHeader[] = "Proc-Type";
  829. char* line = XSTRNSTR((char*)buff, encHeader, PEM_LINE_LEN);
  830. if (line) {
  831. char* newline;
  832. char* finish;
  833. char* start = XSTRNSTR(line, "DES", PEM_LINE_LEN);
  834. if (!start)
  835. start = XSTRNSTR(line, "AES", PEM_LINE_LEN);
  836. if (!start) return SSL_BAD_FILE;
  837. if (!info) return SSL_BAD_FILE;
  838. finish = XSTRNSTR(start, ",", PEM_LINE_LEN);
  839. if (start && finish && (start < finish)) {
  840. newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN);
  841. XMEMCPY(info->name, start, finish - start);
  842. info->name[finish - start] = 0;
  843. XMEMCPY(info->iv, finish + 1, sizeof(info->iv));
  844. if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN);
  845. if (newline && (newline > finish)) {
  846. info->ivSz = (word32)(newline - (finish + 1));
  847. info->set = 1;
  848. }
  849. else
  850. return SSL_BAD_FILE;
  851. }
  852. else
  853. return SSL_BAD_FILE;
  854. /* eat blank line */
  855. while (*newline == '\r' || *newline == '\n')
  856. newline++;
  857. headerEnd = newline;
  858. }
  859. }
  860. #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
  861. /* find footer */
  862. footerEnd = XSTRNSTR((char*)buff, footer, sz);
  863. if (!footerEnd) return SSL_BAD_FILE;
  864. consumedEnd = footerEnd + XSTRLEN(footer);
  865. if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
  866. /* eat end of line */
  867. if (consumedEnd[0] == '\n')
  868. consumedEnd++;
  869. else if (consumedEnd[1] == '\n')
  870. consumedEnd += 2;
  871. else
  872. return SSL_BAD_FILE;
  873. }
  874. if (info)
  875. info->consumed = (long)(consumedEnd - (char*)buff);
  876. /* set up der buffer */
  877. neededSz = (long)(footerEnd - headerEnd);
  878. if (neededSz > sz || neededSz < 0) return SSL_BAD_FILE;
  879. der->buffer = (byte*) XMALLOC(neededSz, heap, dynamicType);
  880. if (!der->buffer) return MEMORY_ERROR;
  881. der->length = (word32)neededSz;
  882. if (Base64_Decode((byte*)headerEnd, (word32)neededSz, der->buffer,
  883. &der->length) < 0)
  884. return SSL_BAD_FILE;
  885. if (pkcs8)
  886. return ToTraditional(der->buffer, der->length);
  887. #ifdef OPENSSL_EXTRA
  888. if (pkcs8Enc) {
  889. int passwordSz;
  890. char password[80];
  891. if (!info || !info->ctx || !info->ctx->passwd_cb)
  892. return SSL_BAD_FILE; /* no callback error */
  893. passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
  894. info->ctx->userdata);
  895. return ToTraditionalEnc(der->buffer, der->length, password,
  896. passwordSz);
  897. }
  898. #endif
  899. return 0;
  900. }
  901. /* process the buffer buff, legnth sz, into ctx of format and type
  902. used tracks bytes consumed, userChain specifies a user cert chain
  903. to pass during the handshake */
  904. static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
  905. long sz, int format, int type, CYASSL* ssl,
  906. long* used, int userChain)
  907. {
  908. EncryptedInfo info;
  909. buffer der; /* holds DER or RAW (for NTRU) */
  910. int ret;
  911. int dynamicType = 0;
  912. int eccKey = 0;
  913. void* heap = ctx ? ctx->heap : NULL;
  914. info.set = 0;
  915. info.ctx = ctx;
  916. info.consumed = 0;
  917. der.buffer = 0;
  918. (void)dynamicType;
  919. if (used)
  920. *used = sz; /* used bytes default to sz, PEM chain may shorten*/
  921. if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
  922. && format != SSL_FILETYPE_RAW)
  923. return SSL_BAD_FILETYPE;
  924. if (type == CA_TYPE)
  925. dynamicType = DYNAMIC_TYPE_CA;
  926. else if (type == CERT_TYPE)
  927. dynamicType = DYNAMIC_TYPE_CERT;
  928. else
  929. dynamicType = DYNAMIC_TYPE_KEY;
  930. if (format == SSL_FILETYPE_PEM) {
  931. ret = PemToDer(buff, sz, type, &der, heap, &info, &eccKey);
  932. if (ret < 0) {
  933. XFREE(der.buffer, heap, dynamicType);
  934. return ret;
  935. }
  936. if (used)
  937. *used = info.consumed;
  938. /* we may have a user cert chain, try to consume */
  939. if (userChain && type == CERT_TYPE && info.consumed < sz) {
  940. byte staticBuffer[FILE_BUFFER_SIZE]; /* tmp chain buffer */
  941. byte* chainBuffer = staticBuffer;
  942. int dynamicBuffer = 0;
  943. word32 bufferSz = sizeof(staticBuffer);
  944. long consumed = info.consumed;
  945. word32 idx = 0;
  946. int gotOne = 0;
  947. if ( (sz - consumed) > (int)bufferSz) {
  948. CYASSL_MSG("Growing Tmp Chain Buffer");
  949. bufferSz = (word32)(sz - consumed);
  950. /* will shrink to actual size */
  951. chainBuffer = (byte*)XMALLOC(bufferSz, heap,
  952. DYNAMIC_TYPE_FILE);
  953. if (chainBuffer == NULL) {
  954. XFREE(der.buffer, heap, dynamicType);
  955. return MEMORY_E;
  956. }
  957. dynamicBuffer = 1;
  958. }
  959. CYASSL_MSG("Processing Cert Chain");
  960. while (consumed < sz) {
  961. buffer part;
  962. info.consumed = 0;
  963. part.buffer = 0;
  964. ret = PemToDer(buff + consumed, sz - consumed, type, &part,
  965. heap, &info, &eccKey);
  966. if (ret == 0) {
  967. gotOne = 1;
  968. if ( (idx + part.length) > bufferSz) {
  969. CYASSL_MSG(" Cert Chain bigger than buffer");
  970. ret = BUFFER_E;
  971. }
  972. else {
  973. c32to24(part.length, &chainBuffer[idx]);
  974. idx += CERT_HEADER_SZ;
  975. XMEMCPY(&chainBuffer[idx], part.buffer,part.length);
  976. idx += part.length;
  977. consumed += info.consumed;
  978. if (used)
  979. *used += info.consumed;
  980. }
  981. }
  982. XFREE(part.buffer, heap, dynamicType);
  983. if (ret == SSL_NO_PEM_HEADER && gotOne) {
  984. CYASSL_MSG("We got one good PEM so stuff at end ok");
  985. break;
  986. }
  987. if (ret < 0) {
  988. CYASSL_MSG(" Error in Cert in Chain");
  989. XFREE(der.buffer, heap, dynamicType);
  990. return ret;
  991. }
  992. CYASSL_MSG(" Consumed another Cert in Chain");
  993. }
  994. CYASSL_MSG("Finished Processing Cert Chain");
  995. if (ctx == NULL) {
  996. CYASSL_MSG("certChain needs context");
  997. return BAD_FUNC_ARG;
  998. }
  999. ctx->certChain.buffer = (byte*)XMALLOC(idx, heap,
  1000. dynamicType);
  1001. if (ctx->certChain.buffer) {
  1002. ctx->certChain.length = idx;
  1003. XMEMCPY(ctx->certChain.buffer, chainBuffer, idx);
  1004. }
  1005. if (dynamicBuffer)
  1006. XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
  1007. if (ctx->certChain.buffer == NULL) {
  1008. XFREE(der.buffer, heap, dynamicType);
  1009. return MEMORY_E;
  1010. }
  1011. }
  1012. }
  1013. else { /* ASN1 (DER) or RAW (NTRU) */
  1014. der.buffer = (byte*) XMALLOC(sz, heap, dynamicType);
  1015. if (!der.buffer) return MEMORY_ERROR;
  1016. XMEMCPY(der.buffer, buff, sz);
  1017. der.length = (word32)sz;
  1018. }
  1019. #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
  1020. if (info.set) {
  1021. /* decrypt */
  1022. char password[80];
  1023. int passwordSz;
  1024. byte key[AES_256_KEY_SIZE];
  1025. byte iv[AES_IV_SIZE];
  1026. if (!ctx || !ctx->passwd_cb) {
  1027. XFREE(der.buffer, heap, dynamicType);
  1028. return NO_PASSWORD;
  1029. }
  1030. /* use file's salt for key derivation, hex decode first */
  1031. if (Base16_Decode(info.iv, info.ivSz, info.iv, &info.ivSz) != 0) {
  1032. XFREE(der.buffer, heap, dynamicType);
  1033. return ASN_INPUT_E;
  1034. }
  1035. passwordSz = ctx->passwd_cb(password, sizeof(password), 0,
  1036. ctx->userdata);
  1037. if ( (ret = EVP_BytesToKey(info.name, "MD5", info.iv,
  1038. (byte*)password, passwordSz, 1, key, iv)) <= 0) {
  1039. XFREE(der.buffer, heap, dynamicType);
  1040. return ret;
  1041. }
  1042. if (XSTRNCMP(info.name, "DES-CBC", 7) == 0) {
  1043. Des enc;
  1044. Des_SetKey(&enc, key, info.iv, DES_DECRYPTION);
  1045. Des_CbcDecrypt(&enc, der.buffer, der.buffer, der.length);
  1046. }
  1047. else if (XSTRNCMP(info.name, "DES-EDE3-CBC", 13) == 0) {
  1048. Des3 enc;
  1049. Des3_SetKey(&enc, key, info.iv, DES_DECRYPTION);
  1050. Des3_CbcDecrypt(&enc, der.buffer, der.buffer, der.length);
  1051. }
  1052. else if (XSTRNCMP(info.name, "AES-128-CBC", 13) == 0) {
  1053. Aes enc;
  1054. AesSetKey(&enc, key, AES_128_KEY_SIZE, info.iv, AES_DECRYPTION);
  1055. AesCbcDecrypt(&enc, der.buffer, der.buffer, der.length);
  1056. }
  1057. else if (XSTRNCMP(info.name, "AES-192-CBC", 13) == 0) {
  1058. Aes enc;
  1059. AesSetKey(&enc, key, AES_192_KEY_SIZE, info.iv, AES_DECRYPTION);
  1060. AesCbcDecrypt(&enc, der.buffer, der.buffer, der.length);
  1061. }
  1062. else if (XSTRNCMP(info.name, "AES-256-CBC", 13) == 0) {
  1063. Aes enc;
  1064. AesSetKey(&enc, key, AES_256_KEY_SIZE, info.iv, AES_DECRYPTION);
  1065. AesCbcDecrypt(&enc, der.buffer, der.buffer, der.length);
  1066. }
  1067. else {
  1068. XFREE(der.buffer, heap, dynamicType);
  1069. return SSL_BAD_FILE;
  1070. }
  1071. }
  1072. #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
  1073. if (type == CA_TYPE) {
  1074. if (ctx == NULL) {
  1075. CYASSL_MSG("Need context for CA load");
  1076. XFREE(der.buffer, heap, dynamicType);
  1077. return BAD_FUNC_ARG;
  1078. }
  1079. return AddCA(ctx->cm, der, CYASSL_USER_CA, ctx->verifyPeer);
  1080. /* takes der over */
  1081. }
  1082. else if (type == CERT_TYPE) {
  1083. if (ssl) {
  1084. if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
  1085. XFREE(ssl->buffers.certificate.buffer, heap,
  1086. dynamicType);
  1087. ssl->buffers.certificate = der;
  1088. ssl->buffers.weOwnCert = 1;
  1089. }
  1090. else if (ctx) {
  1091. if (ctx->certificate.buffer)
  1092. XFREE(ctx->certificate.buffer, heap, dynamicType);
  1093. ctx->certificate = der; /* takes der over */
  1094. }
  1095. }
  1096. else if (type == PRIVATEKEY_TYPE) {
  1097. if (ssl) {
  1098. if (ssl->buffers.weOwnKey && ssl->buffers.key.buffer)
  1099. XFREE(ssl->buffers.key.buffer, heap, dynamicType);
  1100. ssl->buffers.key = der;
  1101. ssl->buffers.weOwnKey = 1;
  1102. }
  1103. else if (ctx) {
  1104. if (ctx->privateKey.buffer)
  1105. XFREE(ctx->privateKey.buffer, heap, dynamicType);
  1106. ctx->privateKey = der; /* takes der over */
  1107. }
  1108. }
  1109. else {
  1110. XFREE(der.buffer, heap, dynamicType);
  1111. return SSL_BAD_CERTTYPE;
  1112. }
  1113. if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
  1114. #ifndef NO_RSA
  1115. if (!eccKey) {
  1116. /* make sure RSA key can be used */
  1117. RsaKey key;
  1118. word32 idx = 0;
  1119. InitRsaKey(&key, 0);
  1120. if (RsaPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
  1121. #ifdef HAVE_ECC
  1122. /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
  1123. eccKey = 1; /* so try it out */
  1124. #endif
  1125. if (!eccKey) {
  1126. FreeRsaKey(&key);
  1127. return SSL_BAD_FILE;
  1128. }
  1129. }
  1130. FreeRsaKey(&key);
  1131. }
  1132. #endif
  1133. #ifdef HAVE_ECC
  1134. if (eccKey ) {
  1135. /* make sure ECC key can be used */
  1136. word32 idx = 0;
  1137. ecc_key key;
  1138. ecc_init(&key);
  1139. if (EccPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
  1140. ecc_free(&key);
  1141. return SSL_BAD_FILE;
  1142. }
  1143. ecc_free(&key);
  1144. ctx->haveStaticECC = 1;
  1145. if (ssl)
  1146. ssl->options.haveStaticECC = 1;
  1147. }
  1148. #endif /* HAVE_ECC */
  1149. }
  1150. else if (type == CERT_TYPE) {
  1151. DecodedCert cert;
  1152. CYASSL_MSG("Checking cert signature type");
  1153. InitDecodedCert(&cert, der.buffer, der.length, heap);
  1154. if (DecodeToKey(&cert, 0) < 0) {
  1155. CYASSL_MSG("Decode to key failed");
  1156. return SSL_BAD_FILE;
  1157. }
  1158. switch (cert.signatureOID) {
  1159. case CTC_SHAwECDSA:
  1160. case CTC_SHA256wECDSA:
  1161. case CTC_SHA384wECDSA:
  1162. case CTC_SHA512wECDSA:
  1163. CYASSL_MSG("ECDSA cert signature");
  1164. if (ctx)
  1165. ctx->haveECDSAsig = 1;
  1166. if (ssl)
  1167. ssl->options.haveECDSAsig = 1;
  1168. break;
  1169. default:
  1170. CYASSL_MSG("Not ECDSA cert signature");
  1171. break;
  1172. }
  1173. FreeDecodedCert(&cert);
  1174. }
  1175. return SSL_SUCCESS;
  1176. }
  1177. /* CA PEM file for verification, may have multiple/chain certs to process */
  1178. static int ProcessChainBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
  1179. long sz, int format, int type, CYASSL* ssl)
  1180. {
  1181. long used = 0;
  1182. int ret = 0;
  1183. int gotOne = 0;
  1184. CYASSL_MSG("Processing CA PEM file");
  1185. while (used < sz) {
  1186. long consumed = 0;
  1187. ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
  1188. &consumed, 0);
  1189. if (ret == SSL_NO_PEM_HEADER && gotOne) {
  1190. CYASSL_MSG("We got one good PEM file so stuff at end ok");
  1191. ret = SSL_SUCCESS;
  1192. break;
  1193. }
  1194. if (ret < 0)
  1195. break;
  1196. CYASSL_MSG(" Processed a CA");
  1197. gotOne = 1;
  1198. used += consumed;
  1199. }
  1200. return ret;
  1201. }
  1202. #ifndef NO_FILESYSTEM
  1203. #if defined(EBSNET)
  1204. #define XFILE int
  1205. #define XFOPEN(NAME, MODE) vf_open((const char *)NAME, VO_RDONLY, 0);
  1206. #define XFSEEK vf_lseek
  1207. #define XFTELL vf_tell
  1208. #define XREWIND vf_rewind
  1209. #define XFREAD(BUF, SZ, AMT, FD) vf_read(FD, BUF, SZ*AMT)
  1210. #define XFCLOSE vf_close
  1211. #define XSEEK_END VSEEK_END
  1212. #define XBADFILE -1
  1213. #elif defined(LSR_FS)
  1214. #include <fs.h>
  1215. #define XFILE struct fs_file*
  1216. #define XFOPEN(NAME, MODE) fs_open((char*)NAME);
  1217. #define XFSEEK(F, O, W) (void)F
  1218. #define XFTELL(F) (F)->len
  1219. #define XREWIND(F) (void)F
  1220. #define XFREAD(BUF, SZ, AMT, F) fs_read(F, (char*)BUF, SZ*AMT)
  1221. #define XFCLOSE fs_close
  1222. #define XSEEK_END 0
  1223. #define XBADFILE NULL
  1224. #elif defined(FREESCALE_MQX)
  1225. #define XFILE MQX_FILE_PTR
  1226. #define XFOPEN fopen
  1227. #define XFSEEK fseek
  1228. #define XFTELL ftell
  1229. #define XREWIND(F) fseek(F, 0, IO_SEEK_SET)
  1230. #define XFREAD fread
  1231. #define XFCLOSE fclose
  1232. #define XSEEK_END IO_SEEK_END
  1233. #define XBADFILE NULL
  1234. #elif defined(MICRIUM)
  1235. #include <fs.h>
  1236. #define XFILE FS_FILE*
  1237. #define XFOPEN fs_fopen
  1238. #define XFSEEK fs_fseek
  1239. #define XFTELL fs_ftell
  1240. #define XREWIND fs_rewind
  1241. #define XFREAD fs_fread
  1242. #define XFCLOSE fs_fclose
  1243. #define XSEEK_END FS_SEEK_END
  1244. #define XBADFILE NULL
  1245. #else
  1246. /* stdio, default case */
  1247. #define XFILE FILE*
  1248. #define XFOPEN fopen
  1249. #define XFSEEK fseek
  1250. #define XFTELL ftell
  1251. #define XREWIND rewind
  1252. #define XFREAD fread
  1253. #define XFCLOSE fclose
  1254. #define XSEEK_END SEEK_END
  1255. #define XBADFILE NULL
  1256. #endif
  1257. /* process a file with name fname into ctx of format and type
  1258. userChain specifies a user certificate chain to pass during handshake */
  1259. int ProcessFile(CYASSL_CTX* ctx, const char* fname, int format, int type,
  1260. CYASSL* ssl, int userChain, CYASSL_CRL* crl)
  1261. {
  1262. byte staticBuffer[FILE_BUFFER_SIZE];
  1263. byte* myBuffer = staticBuffer;
  1264. int dynamic = 0;
  1265. int ret;
  1266. long sz = 0;
  1267. XFILE file;
  1268. void* heapHint = ctx ? ctx->heap : NULL;
  1269. (void)crl;
  1270. (void)heapHint;
  1271. if (fname == NULL) return SSL_BAD_FILE;
  1272. file = XFOPEN(fname, "rb");
  1273. if (file == XBADFILE) return SSL_BAD_FILE;
  1274. XFSEEK(file, 0, XSEEK_END);
  1275. sz = XFTELL(file);
  1276. XREWIND(file);
  1277. if (sz > (long)sizeof(staticBuffer)) {
  1278. CYASSL_MSG("Getting dynamic buffer");
  1279. myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
  1280. if (myBuffer == NULL) {
  1281. XFCLOSE(file);
  1282. return SSL_BAD_FILE;
  1283. }
  1284. dynamic = 1;
  1285. }
  1286. if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
  1287. ret = SSL_BAD_FILE;
  1288. else {
  1289. if (type == CA_TYPE && format == SSL_FILETYPE_PEM)
  1290. ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
  1291. #ifdef HAVE_CRL
  1292. else if (type == CRL_TYPE)
  1293. ret = BufferLoadCRL(crl, myBuffer, sz, format);
  1294. #endif
  1295. else
  1296. ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
  1297. userChain);
  1298. }
  1299. XFCLOSE(file);
  1300. if (dynamic) XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
  1301. return ret;
  1302. }
  1303. /* loads file then loads each file in path, no c_rehash */
  1304. int CyaSSL_CTX_load_verify_locations(CYASSL_CTX* ctx, const char* file,
  1305. const char* path)
  1306. {
  1307. int ret = SSL_SUCCESS;
  1308. CYASSL_ENTER("CyaSSL_CTX_load_verify_locations");
  1309. (void)path;
  1310. if (ctx == NULL || (file == NULL && path == NULL) )
  1311. return SSL_FAILURE;
  1312. if (file)
  1313. ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
  1314. if (ret == SSL_SUCCESS && path) {
  1315. /* try to load each regular file in path */
  1316. #ifdef USE_WINDOWS_API
  1317. WIN32_FIND_DATAA FindFileData;
  1318. HANDLE hFind;
  1319. char name[MAX_FILENAME_SZ];
  1320. XMEMSET(name, 0, sizeof(name));
  1321. XSTRNCPY(name, path, MAX_FILENAME_SZ - 4);
  1322. XSTRNCAT(name, "\\*", 3);
  1323. hFind = FindFirstFileA(name, &FindFileData);
  1324. if (hFind == INVALID_HANDLE_VALUE) {
  1325. CYASSL_MSG("FindFirstFile for path verify locations failed");
  1326. return BAD_PATH_ERROR;
  1327. }
  1328. do {
  1329. if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
  1330. XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 3);
  1331. XSTRNCAT(name, "\\", 2);
  1332. XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2);
  1333. ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
  1334. NULL);
  1335. }
  1336. } while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData));
  1337. FindClose(hFind);
  1338. #elif !defined(NO_CYASSL_DIR)
  1339. struct dirent* entry;
  1340. DIR* dir = opendir(path);
  1341. if (dir == NULL) {
  1342. CYASSL_MSG("opendir path verify locations failed");
  1343. return BAD_PATH_ERROR;
  1344. }
  1345. while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) {
  1346. if (entry->d_type & DT_REG) {
  1347. char name[MAX_FILENAME_SZ];
  1348. XMEMSET(name, 0, sizeof(name));
  1349. XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
  1350. XSTRNCAT(name, "/", 1);
  1351. XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
  1352. ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
  1353. NULL);
  1354. }
  1355. }
  1356. closedir(dir);
  1357. #endif
  1358. }
  1359. return ret;
  1360. }
  1361. /* Verify the ceritficate, 1 for success, < 0 for error */
  1362. int CyaSSL_CertManagerVerifyBuffer(CYASSL_CERT_MANAGER* cm, const byte* buff,
  1363. int sz, int format)
  1364. {
  1365. int ret = 0;
  1366. int eccKey = 0; /* not used */
  1367. DecodedCert cert;
  1368. buffer der;
  1369. CYASSL_ENTER("CyaSSL_CertManagerVerifyBuffer");
  1370. der.buffer = NULL;
  1371. der.length = 0;
  1372. if (format == SSL_FILETYPE_PEM) {
  1373. EncryptedInfo info;
  1374. info.set = 0;
  1375. info.ctx = NULL;
  1376. info.consumed = 0;
  1377. ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, &info, &eccKey);
  1378. InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
  1379. }
  1380. else
  1381. InitDecodedCert(&cert, (byte*)buff, sz, cm->heap);
  1382. if (ret == 0)
  1383. ret = ParseCertRelative(&cert, CERT_TYPE, 1, cm);
  1384. #ifdef HAVE_CRL
  1385. if (ret == 0 && cm->crlEnabled)
  1386. ret = CheckCertCRL(cm->crl, &cert);
  1387. #endif
  1388. FreeDecodedCert(&cert);
  1389. XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CERT);
  1390. return ret;
  1391. }
  1392. /* Verify the ceritficate, 1 for success, < 0 for error */
  1393. int CyaSSL_CertManagerVerify(CYASSL_CERT_MANAGER* cm, const char* fname,
  1394. int format)
  1395. {
  1396. int ret = SSL_FATAL_ERROR;
  1397. byte staticBuffer[FILE_BUFFER_SIZE];
  1398. byte* myBuffer = staticBuffer;
  1399. int dynamic = 0;
  1400. long sz = 0;
  1401. XFILE file = XFOPEN(fname, "rb");
  1402. CYASSL_ENTER("CyaSSL_CertManagerVerify");
  1403. if (file == XBADFILE) return SSL_BAD_FILE;

Large files files are truncated, but you can click here to view the full file