3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
5 * This file is part of CyaSSL.
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.
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.
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
33 #include <cyassl/ssl.h>
34 #include <cyassl/internal.h>
35 #include <cyassl/error.h>
36 #include <cyassl/ctaocrypt/coding.h>
38 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
39 #include <cyassl/openssl/evp.h>
43 /* openssl headers begin */
44 #include <cyassl/openssl/hmac.h>
45 #include <cyassl/openssl/crypto.h>
46 #include <cyassl/openssl/des.h>
47 #include <cyassl/openssl/bn.h>
48 #include <cyassl/openssl/dh.h>
49 #include <cyassl/openssl/rsa.h>
50 #include <cyassl/openssl/pem.h>
51 /* openssl headers end, cyassl internal headers next */
52 #include <cyassl/ctaocrypt/hmac.h>
53 #include <cyassl/ctaocrypt/random.h>
54 #include <cyassl/ctaocrypt/des3.h>
55 #include <cyassl/ctaocrypt/md4.h>
56 #include <cyassl/ctaocrypt/md5.h>
57 #include <cyassl/ctaocrypt/arc4.h>
59 #include <cyassl/ctaocrypt/sha512.h>
64 #if !defined(USE_WINDOWS_API) && !defined(NO_CYASSL_DIR)
67 #endif /* NO_FILESYSTEM */
72 static INLINE word32 min(word32 a, word32 b)
80 char* mystrnstr(const char* s1, const char* s2, unsigned int n)
82 unsigned int s2_len = XSTRLEN(s2);
87 while (n >= s2_len && s1[0]) {
89 if (XMEMCMP(s1, s2, s2_len) == 0)
99 CYASSL_CTX* CyaSSL_CTX_new(CYASSL_METHOD* method)
101 CYASSL_CTX* ctx = NULL;
103 CYASSL_ENTER("CYASSL_CTX_new");
108 ctx = (CYASSL_CTX*) XMALLOC(sizeof(CYASSL_CTX), 0, DYNAMIC_TYPE_CTX);
110 if (InitSSL_Ctx(ctx, method) < 0) {
111 CYASSL_MSG("Init CTX failed");
112 CyaSSL_CTX_free(ctx);
117 CYASSL_LEAVE("CYASSL_CTX_new", 0);
122 void CyaSSL_CTX_free(CYASSL_CTX* ctx)
124 CYASSL_ENTER("SSL_CTX_free");
127 CYASSL_LEAVE("SSL_CTX_free", 0);
131 CYASSL* CyaSSL_new(CYASSL_CTX* ctx)
135 CYASSL_ENTER("SSL_new");
140 ssl = (CYASSL*) XMALLOC(sizeof(CYASSL), ctx->heap,DYNAMIC_TYPE_SSL);
142 if (InitSSL(ssl, ctx) < 0) {
147 CYASSL_LEAVE("SSL_new", 0);
152 void CyaSSL_free(CYASSL* ssl)
154 CYASSL_ENTER("SSL_free");
157 CYASSL_LEAVE("SSL_free", 0);
161 int CyaSSL_set_fd(CYASSL* ssl, int fd)
163 CYASSL_ENTER("SSL_set_fd");
164 ssl->rfd = fd; /* not used directly to allow IO callbacks */
167 ssl->IOCB_ReadCtx = &ssl->rfd;
168 ssl->IOCB_WriteCtx = &ssl->wfd;
170 CYASSL_LEAVE("SSL_set_fd", SSL_SUCCESS);
175 int CyaSSL_get_fd(const CYASSL* ssl)
177 CYASSL_ENTER("SSL_get_fd");
178 CYASSL_LEAVE("SSL_get_fd", ssl->rfd);
183 int CyaSSL_negotiate(CYASSL* ssl)
185 int err = SSL_FATAL_ERROR;
187 CYASSL_ENTER("CyaSSL_negotiate");
188 #ifndef NO_CYASSL_SERVER
189 if (ssl->options.side == SERVER_END)
190 err = CyaSSL_accept(ssl);
193 #ifndef NO_CYASSL_CLIENT
194 if (ssl->options.side == CLIENT_END)
195 err = CyaSSL_connect(ssl);
198 CYASSL_LEAVE("CyaSSL_negotiate", err);
200 if (err == SSL_SUCCESS)
207 /* server Diffie-Hellman parameters */
208 int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz,
209 const unsigned char* g, int gSz)
213 CYASSL_ENTER("CyaSSL_SetTmpDH");
214 if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
216 if (ssl->options.side != SERVER_END)
219 if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
220 XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
221 if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
222 XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
224 ssl->buffers.weOwnDH = 1; /* SSL owns now */
225 ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
227 if (ssl->buffers.serverDH_P.buffer == NULL)
230 ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->ctx->heap,
232 if (ssl->buffers.serverDH_G.buffer == NULL) {
233 XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
237 ssl->buffers.serverDH_P.length = pSz;
238 ssl->buffers.serverDH_G.length = gSz;
240 XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
241 XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
243 ssl->options.haveDH = 1;
245 havePSK = ssl->options.havePSK;
247 InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH,
248 havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig,
249 ssl->options.haveStaticECC, ssl->options.side);
251 CYASSL_LEAVE("CyaSSL_SetTmpDH", 0);
256 int CyaSSL_write(CYASSL* ssl, const void* data, int sz)
260 CYASSL_ENTER("SSL_write()");
266 ret = SendData(ssl, data, sz);
268 CYASSL_LEAVE("SSL_write()", ret);
271 return SSL_FATAL_ERROR;
277 int CyaSSL_read(CYASSL* ssl, void* data, int sz)
281 CYASSL_ENTER("SSL_read()");
287 ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE));
289 CYASSL_LEAVE("SSL_read()", ret);
292 return SSL_FATAL_ERROR;
298 int CyaSSL_shutdown(CYASSL* ssl)
300 CYASSL_ENTER("SSL_shutdown()");
302 if (ssl->options.quietShutdown) {
303 CYASSL_MSG("quiet shutdown, no close notify sent");
307 /* try to send close notify, not an error if can't */
308 if (!ssl->options.isClosed && !ssl->options.connReset &&
309 !ssl->options.sentNotify) {
310 ssl->error = SendAlert(ssl, alert_warning, close_notify);
311 if (ssl->error < 0) {
312 CYASSL_ERROR(ssl->error);
313 return SSL_FATAL_ERROR;
315 ssl->options.sentNotify = 1; /* don't send close_notify twice */
318 CYASSL_LEAVE("SSL_shutdown()", ssl->error);
320 ssl->error = SSL_ERROR_SYSCALL; /* simulate OpenSSL behavior */
326 int CyaSSL_get_error(CYASSL* ssl, int ret)
328 CYASSL_ENTER("SSL_get_error");
329 CYASSL_LEAVE("SSL_get_error", ssl->error);
331 return SSL_ERROR_NONE;
333 if (ssl->error == WANT_READ)
334 return SSL_ERROR_WANT_READ; /* convert to OpenSSL type */
335 else if (ssl->error == WANT_WRITE)
336 return SSL_ERROR_WANT_WRITE; /* convert to OpenSSL type */
337 else if (ssl->error == ZERO_RETURN)
338 return SSL_ERROR_ZERO_RETURN; /* convert to OpenSSL type */
343 int CyaSSL_want_read(CYASSL* ssl)
345 CYASSL_ENTER("SSL_want_read");
346 if (ssl->error == WANT_READ)
353 int CyaSSL_want_write(CYASSL* ssl)
355 CYASSL_ENTER("SSL_want_write");
356 if (ssl->error == WANT_WRITE)
363 char* CyaSSL_ERR_error_string(unsigned long errNumber, char* data)
365 static const char* msg = "Please supply a buffer for error string";
367 CYASSL_ENTER("ERR_error_string");
369 SetErrorString(errNumber, data);
377 void CyaSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
379 CYASSL_ENTER("CyaSSL_ERR_error_string_n");
380 if (len) CyaSSL_ERR_error_string(e, buf);
384 CYASSL_CERT_MANAGER* CyaSSL_CertManagerNew(void)
386 CYASSL_CERT_MANAGER* cm = NULL;
388 CYASSL_ENTER("CyaSSL_CertManagerNew");
390 cm = (CYASSL_CERT_MANAGER*) XMALLOC(sizeof(CYASSL_CERT_MANAGER), 0,
391 DYNAMIC_TYPE_CERT_MANAGER);
395 cm->caCacheCallback = NULL;
399 cm->cbMissingCRL = NULL;
401 if (InitMutex(&cm->caLock) != 0) {
402 CYASSL_MSG("Bad mutex init");
403 CyaSSL_CertManagerFree(cm);
412 void CyaSSL_CertManagerFree(CYASSL_CERT_MANAGER* cm)
414 CYASSL_ENTER("CyaSSL_CertManagerFree");
421 FreeSigners(cm->caList, NULL);
422 FreeMutex(&cm->caLock);
423 XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
431 #ifndef NO_FILESYSTEM
433 void CyaSSL_ERR_print_errors_fp(FILE* fp, int err)
435 char data[MAX_ERROR_SZ + 1];
437 CYASSL_ENTER("CyaSSL_ERR_print_errors_fp");
438 SetErrorString(err, data);
439 fprintf(fp, "%s", data);
445 int CyaSSL_pending(CYASSL* ssl)
447 CYASSL_ENTER("SSL_pending");
448 return ssl->buffers.clearOutputBuffer.length;
452 /* trun on handshake group messages for context */
453 int CyaSSL_CTX_set_group_messages(CYASSL_CTX* ctx)
458 ctx->groupMessages = 1;
464 #ifndef NO_CYASSL_CLIENT
465 /* connect enough to get peer cert chain */
466 int CyaSSL_connect_cert(CYASSL* ssl)
473 ssl->options.certOnly = 1;
474 ret = CyaSSL_connect(ssl);
475 ssl->options.certOnly = 0;
482 /* trun on handshake group messages for ssl object */
483 int CyaSSL_set_group_messages(CYASSL* ssl)
488 ssl->options.groupMessages = 1;
494 int CyaSSL_SetVersion(CYASSL* ssl, int version)
498 CYASSL_ENTER("CyaSSL_SetVersion");
501 CYASSL_MSG("Bad function argument");
507 ssl->version = MakeSSLv3();
512 ssl->version = MakeTLSv1();
516 ssl->version = MakeTLSv1_1();
520 ssl->version = MakeTLSv1_2();
525 CYASSL_MSG("Bad function argument");
530 havePSK = ssl->options.havePSK;
533 InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
534 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
535 ssl->options.haveStaticECC, ssl->options.side);
541 /* does CA already exist on signer list */
542 int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash)
547 if (LockMutex(&cm->caLock) != 0)
549 signers = cm->caList;
551 if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
555 signers = signers->next;
557 UnLockMutex(&cm->caLock);
563 /* return CA if found, otherwise NULL */
564 Signer* GetCA(void* vp, byte* hash)
566 CYASSL_CERT_MANAGER* cm = (CYASSL_CERT_MANAGER*)vp;
573 signers = cm->caList;
575 if (LockMutex(&cm->caLock) != 0)
578 if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
582 signers = signers->next;
584 UnLockMutex(&cm->caLock);
590 /* owns der, internal now uses too */
591 /* type flag ids from user or from chain received during verify
592 don't allow chain ones to be added w/o isCA extension */
593 int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
599 CYASSL_MSG("Adding a CA");
600 InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
601 ret = ParseCert(&cert, CA_TYPE, verify, cm);
602 CYASSL_MSG(" Parsed new CA");
604 if (ret == 0 && cert.isCA == 0 && type != CYASSL_USER_CA) {
605 CYASSL_MSG(" Can't add as CA if not actually one");
608 else if (ret == 0 && AlreadySigner(cm, cert.subjectHash)) {
609 CYASSL_MSG(" Already have this CA, not adding again");
613 /* take over signer parts */
614 signer = MakeSigner(cm->heap);
618 signer->keyOID = cert.keyOID;
619 signer->publicKey = cert.publicKey;
620 signer->pubKeySize = cert.pubKeySize;
621 signer->name = cert.subjectCN;
622 XMEMCPY(signer->hash, cert.subjectHash, SHA_DIGEST_SIZE);
623 signer->next = NULL; /* in case lock fails */
625 cert.publicKey = 0; /* don't free here */
628 if (LockMutex(&cm->caLock) == 0) {
629 signer->next = cm->caList;
630 cm->caList = signer; /* takes ownership */
631 UnLockMutex(&cm->caLock);
632 if (cm->caCacheCallback)
633 cm->caCacheCallback(der.buffer, (int)der.length, type);
636 CYASSL_MSG(" CA Mutex Lock failed");
637 ret = BAD_MUTEX_ERROR;
638 FreeSigners(signer, cm->heap);
643 CYASSL_MSG(" Freeing Parsed CA");
644 FreeDecodedCert(&cert);
645 CYASSL_MSG(" Freeing der CA");
646 XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_CA);
647 CYASSL_MSG(" OK Freeing der CA");
649 CYASSL_LEAVE("AddCA", ret);
650 if (ret == 0) return SSL_SUCCESS;
655 #ifndef NO_SESSION_CACHE
657 /* basic config gives a cache with 33 sessions, adequate for clients and
660 MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
661 aren't under heavy load, basically allows 200 new sessions per minute
663 BIG_SESSION_CACHE yields 20,0027 sessions
665 HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
666 allows over 13,000 new sessions per minute or over 200 new sessions per
669 SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
670 or systems where the default of nearly 3kB is too much RAM, this define
671 uses less than 500 bytes RAM
673 #ifdef HUGE_SESSION_CACHE
674 #define SESSIONS_PER_ROW 11
675 #define SESSION_ROWS 5981
676 #elif defined(BIG_SESSION_CACHE)
677 #define SESSIONS_PER_ROW 7
678 #define SESSION_ROWS 2861
679 #elif defined(MEDIUM_SESSION_CACHE)
680 #define SESSIONS_PER_ROW 5
681 #define SESSION_ROWS 211
682 #elif defined(SMALL_SESSION_CACHE)
683 #define SESSIONS_PER_ROW 2
684 #define SESSION_ROWS 3
686 #define SESSIONS_PER_ROW 3
687 #define SESSION_ROWS 11
690 typedef struct SessionRow {
691 int nextIdx; /* where to place next one */
692 int totalCount; /* sessions ever on this row */
693 CYASSL_SESSION Sessions[SESSIONS_PER_ROW];
696 static SessionRow SessionCache[SESSION_ROWS];
698 static CyaSSL_Mutex session_mutex; /* SessionCache mutex */
700 #endif /* NO_SESSION_CACHE */
703 /* Remove PEM header/footer, convert to ASN1, store any encrypted data
704 info->consumed tracks of PEM bytes consumed in case multiple parts */
705 int PemToDer(const unsigned char* buff, long sz, int type,
706 buffer* der, void* heap, EncryptedInfo* info, int* eccKey)
708 char header[PEM_LINE_LEN];
709 char footer[PEM_LINE_LEN];
722 if (type == CERT_TYPE || type == CA_TYPE) {
723 XSTRNCPY(header, "-----BEGIN CERTIFICATE-----", sizeof(header));
724 XSTRNCPY(footer, "-----END CERTIFICATE-----", sizeof(footer));
725 dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
727 } else if (type == DH_PARAM_TYPE) {
728 XSTRNCPY(header, "-----BEGIN DH PARAMETERS-----", sizeof(header));
729 XSTRNCPY(footer, "-----END DH PARAMETERS-----", sizeof(footer));
730 dynamicType = DYNAMIC_TYPE_KEY;
731 } else if (type == CRL_TYPE) {
732 XSTRNCPY(header, "-----BEGIN X509 CRL-----", sizeof(header));
733 XSTRNCPY(footer, "-----END X509 CRL-----", sizeof(footer));
734 dynamicType = DYNAMIC_TYPE_CRL;
736 XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header));
737 XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----", sizeof(footer));
738 dynamicType = DYNAMIC_TYPE_KEY;
742 headerEnd = XSTRNSTR((char*)buff, header, sz);
743 if (!headerEnd && type == PRIVATEKEY_TYPE) { /* may be pkcs8 */
744 XSTRNCPY(header, "-----BEGIN PRIVATE KEY-----", sizeof(header));
745 XSTRNCPY(footer, "-----END PRIVATE KEY-----", sizeof(footer));
747 headerEnd = XSTRNSTR((char*)buff, header, sz);
751 XSTRNCPY(header, "-----BEGIN ENCRYPTED PRIVATE KEY-----",
753 XSTRNCPY(footer, "-----END ENCRYPTED PRIVATE KEY-----",
756 headerEnd = XSTRNSTR((char*)buff, header, sz);
761 if (!headerEnd && type == PRIVATEKEY_TYPE) { /* may be ecc */
762 XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----", sizeof(header));
763 XSTRNCPY(footer, "-----END EC PRIVATE KEY-----", sizeof(footer));
765 headerEnd = XSTRNSTR((char*)buff, header, sz);
769 if (!headerEnd && type == PRIVATEKEY_TYPE) { /* may be dsa */
770 XSTRNCPY(header, "-----BEGIN DSA PRIVATE KEY-----", sizeof(header));
771 XSTRNCPY(footer, "-----END DSA PRIVATE KEY-----", sizeof(footer));
773 headerEnd = XSTRNSTR((char*)buff, header, sz);
777 headerEnd += XSTRLEN(header);
780 if (headerEnd[0] == '\n')
782 else if (headerEnd[1] == '\n')
787 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
789 /* remove encrypted header if there */
790 char encHeader[] = "Proc-Type";
791 char* line = XSTRNSTR((char*)buff, encHeader, PEM_LINE_LEN);
795 char* start = XSTRNSTR(line, "DES", PEM_LINE_LEN);
798 start = XSTRNSTR(line, "AES", PEM_LINE_LEN);
800 if (!start) return SSL_BAD_FILE;
801 if (!info) return SSL_BAD_FILE;
803 finish = XSTRNSTR(start, ",", PEM_LINE_LEN);
805 if (start && finish && (start < finish)) {
806 newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN);
808 XMEMCPY(info->name, start, finish - start);
809 info->name[finish - start] = 0;
810 XMEMCPY(info->iv, finish + 1, sizeof(info->iv));
812 if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN);
813 if (newline && (newline > finish)) {
814 info->ivSz = (word32)(newline - (finish + 1));
824 while (*newline == '\r' || *newline == '\n')
829 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
832 footerEnd = XSTRNSTR((char*)buff, footer, sz);
833 if (!footerEnd) return SSL_BAD_FILE;
835 consumedEnd = footerEnd + XSTRLEN(footer);
838 if (consumedEnd[0] == '\n')
840 else if (consumedEnd[1] == '\n')
846 info->consumed = (long)(consumedEnd - (char*)buff);
848 /* set up der buffer */
849 neededSz = (long)(footerEnd - headerEnd);
850 if (neededSz > sz || neededSz < 0) return SSL_BAD_FILE;
851 der->buffer = (byte*) XMALLOC(neededSz, heap, dynamicType);
852 if (!der->buffer) return MEMORY_ERROR;
853 der->length = neededSz;
855 if (Base64_Decode((byte*)headerEnd, neededSz, der->buffer,
860 return ToTraditional(der->buffer, der->length);
867 if (!info->ctx || !info->ctx->passwd_cb)
868 return SSL_BAD_FILE; /* no callback error */
869 passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
870 info->ctx->userdata);
871 return ToTraditionalEnc(der->buffer, der->length, password,
880 /* process the buffer buff, legnth sz, into ctx of format and type
881 used tracks bytes consumed, userChain specifies a user cert chain
882 to pass during the handshake */
883 static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
884 long sz, int format, int type, CYASSL* ssl,
885 long* used, int userChain)
888 buffer der; /* holds DER or RAW (for NTRU) */
900 *used = sz; /* used bytes default to sz, PEM chain may shorten*/
902 if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
903 && format != SSL_FILETYPE_RAW)
904 return SSL_BAD_FILETYPE;
907 dynamicType = DYNAMIC_TYPE_CA;
908 else if (type == CERT_TYPE)
909 dynamicType = DYNAMIC_TYPE_CERT;
911 dynamicType = DYNAMIC_TYPE_KEY;
913 if (format == SSL_FILETYPE_PEM) {
914 int ret = PemToDer(buff, sz, type, &der, ctx->heap, &info, &eccKey);
916 XFREE(der.buffer, ctx->heap, dynamicType);
920 *used = info.consumed;
921 /* we may have a user cert chain, try to consume */
922 if (userChain && type == CERT_TYPE && info.consumed < sz) {
923 byte staticBuffer[FILE_BUFFER_SIZE]; /* tmp chain buffer */
924 byte* chainBuffer = staticBuffer;
925 int dynamicBuffer = 0;
926 word32 bufferSz = sizeof(staticBuffer);
927 long consumed = info.consumed;
930 if ( (sz - consumed) > (int)bufferSz) {
931 CYASSL_MSG("Growing Tmp Chain Buffer");
932 bufferSz = sz - consumed; /* will shrink to actual size */
933 chainBuffer = (byte*)XMALLOC(bufferSz, ctx->heap,
935 if (chainBuffer == NULL) {
936 XFREE(der.buffer, ctx->heap, dynamicType);
942 CYASSL_MSG("Processing Cert Chain");
943 while (consumed < sz) {
949 ret = PemToDer(buff + consumed, sz - consumed, type, &part,
950 ctx->heap, &info, &eccKey);
952 if ( (idx + part.length) > bufferSz) {
953 CYASSL_MSG(" Cert Chain bigger than buffer");
957 c32to24(part.length, &chainBuffer[idx]);
958 idx += CERT_HEADER_SZ;
959 XMEMCPY(&chainBuffer[idx], part.buffer,part.length);
961 consumed += info.consumed;
963 *used += info.consumed;
967 XFREE(part.buffer, ctx->heap, dynamicType);
969 CYASSL_MSG(" Error in Cert in Chain");
970 XFREE(der.buffer, ctx->heap, dynamicType);
973 CYASSL_MSG(" Consumed another Cert in Chain");
975 left = sz - consumed;
976 if (left > 0 && left < CERT_MIN_SIZE) {
977 CYASSL_MSG(" Non Cert at end of file");
981 CYASSL_MSG("Finished Processing Cert Chain");
982 ctx->certChain.buffer = (byte*)XMALLOC(idx, ctx->heap,
984 if (ctx->certChain.buffer) {
985 ctx->certChain.length = idx;
986 XMEMCPY(ctx->certChain.buffer, chainBuffer, idx);
989 XFREE(chainBuffer, ctx->heap, DYNAMIC_FILE_TYPE);
990 if (ctx->certChain.buffer == NULL) {
991 XFREE(der.buffer, ctx->heap, dynamicType);
996 else { /* ASN1 (DER) or RAW (NTRU) */
997 der.buffer = (byte*) XMALLOC(sz, ctx->heap, dynamicType);
998 if (!der.buffer) return MEMORY_ERROR;
999 XMEMCPY(der.buffer, buff, sz);
1003 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
1010 byte key[AES_256_KEY_SIZE];
1011 byte iv[AES_IV_SIZE];
1013 if (!ctx->passwd_cb) {
1014 XFREE(der.buffer, ctx->heap, dynamicType);
1018 /* use file's salt for key derivation, hex decode first */
1019 if (Base16_Decode(info.iv, info.ivSz, info.iv, &info.ivSz) != 0) {
1020 XFREE(der.buffer, ctx->heap, dynamicType);
1024 passwordSz = ctx->passwd_cb(password, sizeof(password), 0,
1026 if ( (ret = EVP_BytesToKey(info.name, "MD5", info.iv,
1027 (byte*)password, passwordSz, 1, key, iv)) <= 0) {
1028 XFREE(der.buffer, ctx->heap, dynamicType);
1032 if (XSTRNCMP(info.name, "DES-CBC", 7) == 0) {
1034 Des_SetKey(&enc, key, info.iv, DES_DECRYPTION);
1035 Des_CbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1037 else if (XSTRNCMP(info.name, "DES-EDE3-CBC", 13) == 0) {
1039 Des3_SetKey(&enc, key, info.iv, DES_DECRYPTION);
1040 Des3_CbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1042 else if (XSTRNCMP(info.name, "AES-128-CBC", 13) == 0) {
1044 AesSetKey(&enc, key, AES_128_KEY_SIZE, info.iv, AES_DECRYPTION);
1045 AesCbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1047 else if (XSTRNCMP(info.name, "AES-192-CBC", 13) == 0) {
1049 AesSetKey(&enc, key, AES_192_KEY_SIZE, info.iv, AES_DECRYPTION);
1050 AesCbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1052 else if (XSTRNCMP(info.name, "AES-256-CBC", 13) == 0) {
1054 AesSetKey(&enc, key, AES_256_KEY_SIZE, info.iv, AES_DECRYPTION);
1055 AesCbcDecrypt(&enc, der.buffer, der.buffer, der.length);
1058 XFREE(der.buffer, ctx->heap, dynamicType);
1059 return SSL_BAD_FILE;
1062 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
1064 if (type == CA_TYPE)
1065 return AddCA(ctx->cm, der, CYASSL_USER_CA, ctx->verifyPeer);
1066 /* takes der over */
1067 else if (type == CERT_TYPE) {
1069 if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
1070 XFREE(ssl->buffers.certificate.buffer, ctx->heap,
1072 ssl->buffers.certificate = der;
1073 ssl->buffers.weOwnCert = 1;
1076 if (ctx->certificate.buffer)
1077 XFREE(ctx->certificate.buffer, ctx->heap, dynamicType);
1078 ctx->certificate = der; /* takes der over */
1081 else if (type == PRIVATEKEY_TYPE) {
1083 if (ssl->buffers.weOwnKey && ssl->buffers.key.buffer)
1084 XFREE(ssl->buffers.key.buffer, ctx->heap, dynamicType);
1085 ssl->buffers.key = der;
1086 ssl->buffers.weOwnKey = 1;
1089 if (ctx->privateKey.buffer)
1090 XFREE(ctx->privateKey.buffer, ctx->heap, dynamicType);
1091 ctx->privateKey = der; /* takes der over */
1095 XFREE(der.buffer, ctx->heap, dynamicType);
1096 return SSL_BAD_CERTTYPE;
1099 if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
1101 /* make sure RSA key can be used */
1105 InitRsaKey(&key, 0);
1106 if (RsaPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
1108 /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
1109 eccKey = 1; /* so try it out */
1113 return SSL_BAD_FILE;
1120 /* make sure ECC key can be used */
1125 if (EccPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
1127 return SSL_BAD_FILE;
1130 ctx->haveStaticECC = 1;
1132 ssl->options.haveStaticECC = 1;
1134 #endif /* HAVE_ECC */
1136 else if (type == CERT_TYPE) {
1140 CYASSL_MSG("Checking cert signature type");
1141 InitDecodedCert(&cert, der.buffer, der.length, ctx->heap);
1143 if ((ret = DecodeToKey(&cert, 0)) < 0) {
1144 CYASSL_MSG("Decode to key failed");
1145 return SSL_BAD_FILE;
1147 switch (cert.signatureOID) {
1149 case CTC_SHA256wECDSA:
1150 case CTC_SHA384wECDSA:
1151 case CTC_SHA512wECDSA:
1152 CYASSL_MSG("ECDSA cert signature");
1153 ctx->haveECDSAsig = 1;
1155 ssl->options.haveECDSAsig = 1;
1158 CYASSL_MSG("Not ECDSA cert signature");
1162 FreeDecodedCert(&cert);
1171 /* CA PEM file for verification, may have multiple/chain certs to process */
1172 static int ProcessChainBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
1173 long sz, int format, int type, CYASSL* ssl)
1178 CYASSL_MSG("Processing CA PEM file");
1183 ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
1188 CYASSL_MSG(" Processed a CA");
1192 if (left > 0 && left < CERT_MIN_SIZE) { /* non cert stuff at eof */
1193 CYASSL_MSG(" Non CA cert at eof");
1201 #ifndef NO_FILESYSTEM
1205 #define XFOPEN fopen
1206 #define XFSEEK fseek
1207 #define XFTELL ftell
1208 #define XREWIND rewind
1209 #define XFREAD fread
1210 #define XFCLOSE fclose
1211 #define XSEEK_END SEEK_END
1214 #define XFILE FS_FILE
1215 #define XFOPEN fs_fopen
1216 #define XFSEEK fs_fseek
1217 #define XFTELL fs_ftell
1218 #define XREWIND fs_rewind
1219 #define XFREAD fs_fread
1220 #define XFCLOSE fs_fclose
1221 #define XSEEK_END FS_SEEK_END
1225 /* process a file with name fname into ctx of format and type
1226 userChain specifies a user certificate chain to pass during handshake */
1227 int ProcessFile(CYASSL_CTX* ctx, const char* fname, int format, int type,
1228 CYASSL* ssl, int userChain, CYASSL_CRL* crl)
1230 byte staticBuffer[FILE_BUFFER_SIZE];
1231 byte* myBuffer = staticBuffer;
1235 XFILE* file = XFOPEN(fname, "rb");
1239 if (!file) return SSL_BAD_FILE;
1240 XFSEEK(file, 0, XSEEK_END);
1244 if (sz > (long)sizeof(staticBuffer)) {
1245 CYASSL_MSG("Getting dynamic buffer");
1246 myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
1247 if (myBuffer == NULL) {
1249 return SSL_BAD_FILE;
1254 if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0)
1257 if (type == CA_TYPE && format == SSL_FILETYPE_PEM)
1258 ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
1260 else if (type == CRL_TYPE)
1261 ret = BufferLoadCRL(crl, myBuffer, sz, format);
1264 ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
1269 if (dynamic) XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
1275 /* loads file then loads each file in path, no c_rehash */
1276 int CyaSSL_CTX_load_verify_locations(CYASSL_CTX* ctx, const char* file,
1279 int ret = SSL_SUCCESS;
1281 CYASSL_ENTER("CyaSSL_CTX_load_verify_locations");
1284 if (ctx == NULL || (file == NULL && path == NULL) )
1288 ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
1290 if (ret == SSL_SUCCESS && path) {
1291 /* try to load each regular file in path */
1292 #ifdef USE_WINDOWS_API
1293 WIN32_FIND_DATAA FindFileData;
1295 char name[MAX_FILENAME_SZ];
1297 XMEMSET(name, 0, sizeof(name));
1298 XSTRNCPY(name, path, MAX_FILENAME_SZ - 4);
1299 XSTRNCAT(name, "\\*", 3);
1301 hFind = FindFirstFileA(name, &FindFileData);
1302 if (hFind == INVALID_HANDLE_VALUE) {
1303 CYASSL_MSG("FindFirstFile for path verify locations failed");
1304 return BAD_PATH_ERROR;
1308 if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
1309 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 3);
1310 XSTRNCAT(name, "\\", 2);
1311 XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2);
1313 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
1316 } while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData));
1319 #elif !defined(NO_CYASSL_DIR)
1320 struct dirent* entry;
1321 DIR* dir = opendir(path);
1324 CYASSL_MSG("opendir path verify locations failed");
1325 return BAD_PATH_ERROR;
1327 while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) {
1328 if (entry->d_type & DT_REG) {
1329 char name[MAX_FILENAME_SZ];
1331 XMEMSET(name, 0, sizeof(name));
1332 XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
1333 XSTRNCAT(name, "/", 1);
1334 XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
1336 ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE, NULL,0,
1348 /* Verify the ceritficate, 1 for success, < 0 for error */
1349 int CyaSSL_CertManagerVerifyBuffer(CYASSL_CERT_MANAGER* cm, const byte* buff,
1353 int eccKey = 0; /* not used */
1358 CYASSL_ENTER("CyaSSL_CertManagerVerifyBuffer");
1362 if (format == SSL_FILETYPE_PEM) {
1368 ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, &info, &eccKey);
1369 InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
1372 InitDecodedCert(&cert, (byte*)buff, sz, cm->heap);
1375 ret = ParseCertRelative(&cert, CERT_TYPE, 1, cm);
1377 if (ret == 0 && cm->crlEnabled)
1378 ret = CheckCertCRL(cm->crl, &cert);
1381 FreeDecodedCert(&cert);
1382 XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CERT);
1388 /* Verify the ceritficate, 1 for success, < 0 for error */
1389 int CyaSSL_CertManagerVerify(CYASSL_CERT_MANAGER* cm, const char* fname,
1392 int ret = SSL_FATAL_ERROR;
1393 byte staticBuffer[FILE_BUFFER_SIZE];
1394 byte* myBuffer = staticBuffer;
1397 XFILE* file = XFOPEN(fname, "rb");
1399 CYASSL_ENTER("CyaSSL_CertManagerVerify");
1401 if (!file) return SSL_BAD_FILE;
1402 XFSEEK(file, 0, XSEEK_END);
1406 if (sz > (long)sizeof(staticBuffer)) {
1407 CYASSL_MSG("Getting dynamic buffer");
1408 myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
1409 if (myBuffer == NULL) {
1411 return SSL_BAD_FILE;
1416 if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0)
1419 ret = CyaSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
1422 if (dynamic) XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
1430 /* like load verify locations, 1 for success, < 0 for error */
1431 int CyaSSL_CertManagerLoadCA(CYASSL_CERT_MANAGER* cm, const char* file,
1434 int ret = SSL_FATAL_ERROR;
1437 CYASSL_ENTER("CyaSSL_CertManagerLoadCA");
1440 CYASSL_MSG("No CertManager error");
1443 tmp = CyaSSL_CTX_new(CyaSSLv3_client_method());
1446 CYASSL_MSG("CTX new failed");
1451 CyaSSL_CertManagerFree(tmp->cm);
1454 ret = CyaSSL_CTX_load_verify_locations(tmp, file, path);
1456 /* don't loose our good one */
1458 CyaSSL_CTX_free(tmp);
1465 /* turn on CRL if off and compiled in, set options */
1466 int CyaSSL_CertManagerEnableCRL(CYASSL_CERT_MANAGER* cm, int options)
1468 int ret = SSL_SUCCESS;
1472 CYASSL_ENTER("CyaSSL_CertManagerEnableCRL");
1474 return BAD_FUNC_ARG;
1477 if (cm->crl == NULL) {
1478 cm->crl = (CYASSL_CRL*)XMALLOC(sizeof(CYASSL_CRL), cm->heap,
1480 if (cm->crl == NULL)
1483 if (InitCRL(cm->crl, cm) != 0) {
1484 CYASSL_MSG("Init CRL failed");
1491 if (options & CYASSL_CRL_CHECKALL)
1492 cm->crlCheckAll = 1;
1494 ret = NOT_COMPILED_IN;
1501 int CyaSSL_CertManagerDisableCRL(CYASSL_CERT_MANAGER* cm)
1503 CYASSL_ENTER("CyaSSL_CertManagerDisableCRL");
1505 return BAD_FUNC_ARG;
1513 int CyaSSL_CTX_check_private_key(CYASSL_CTX* ctx)
1515 /* TODO: check private against public for RSA match */
1517 CYASSL_ENTER("SSL_CTX_check_private_key");
1525 /* check CRL if enabled, SSL_SUCCESS */
1526 int CyaSSL_CertManagerCheckCRL(CYASSL_CERT_MANAGER* cm, byte* der, int sz)
1531 CYASSL_ENTER("CyaSSL_CertManagerCheckCRL");
1534 return BAD_FUNC_ARG;
1536 if (cm->crlEnabled == 0)
1539 InitDecodedCert(&cert, der, sz, NULL);
1541 ret = ParseCertRelative(&cert, CERT_TYPE, NO_VERIFY, cm);
1543 CYASSL_MSG("ParseCert failed");
1547 ret = CheckCertCRL(cm->crl, &cert);
1549 CYASSL_MSG("CheckCertCRL failed");
1553 FreeDecodedCert(&cert);
1556 return SSL_SUCCESS; /* convert */
1562 int CyaSSL_CertManagerSetCRL_Cb(CYASSL_CERT_MANAGER* cm, CbMissingCRL cb)
1564 CYASSL_ENTER("CyaSSL_CertManagerSetCRL_Cb");
1566 return BAD_FUNC_ARG;
1568 cm->cbMissingCRL = cb;
1574 int CyaSSL_CertManagerLoadCRL(CYASSL_CERT_MANAGER* cm, const char* path,
1575 int type, int monitor)
1577 CYASSL_ENTER("CyaSSL_CertManagerLoadCRL");
1579 return BAD_FUNC_ARG;
1581 if (cm->crl == NULL) {
1582 if (CyaSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
1583 CYASSL_MSG("Enable CRL failed");
1588 return LoadCRL(cm->crl, path, type, monitor);
1592 int CyaSSL_EnableCRL(CYASSL* ssl, int options)
1594 CYASSL_ENTER("CyaSSL_EnableCRL");
1596 return CyaSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
1598 return BAD_FUNC_ARG;
1602 int CyaSSL_DisableCRL(CYASSL* ssl)
1604 CYASSL_ENTER("CyaSSL_DisableCRL");
1606 return CyaSSL_CertManagerDisableCRL(ssl->ctx->cm);
1608 return BAD_FUNC_ARG;
1612 int CyaSSL_LoadCRL(CYASSL* ssl, const char* path, int type, int monitor)
1614 CYASSL_ENTER("CyaSSL_LoadCRL");
1616 return CyaSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
1618 return BAD_FUNC_ARG;
1622 int CyaSSL_SetCRL_Cb(CYASSL* ssl, CbMissingCRL cb)
1624 CYASSL_ENTER("CyaSSL_SetCRL_Cb");
1626 return CyaSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
1628 return BAD_FUNC_ARG;
1632 int CyaSSL_CTX_EnableCRL(CYASSL_CTX* ctx, int options)
1634 CYASSL_ENTER("CyaSSL_CTX_EnableCRL");
1636 return CyaSSL_CertManagerEnableCRL(ctx->cm, options);
1638 return BAD_FUNC_ARG;
1642 int CyaSSL_CTX_DisableCRL(CYASSL_CTX* ctx)
1644 CYASSL_ENTER("CyaSSL_CTX_DisableCRL");
1646 return CyaSSL_CertManagerDisableCRL(ctx->cm);
1648 return BAD_FUNC_ARG;
1652 int CyaSSL_CTX_LoadCRL(CYASSL_CTX* ctx, const char* path, int type, int monitor)
1654 CYASSL_ENTER("CyaSSL_CTX_LoadCRL");
1656 return CyaSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
1658 return BAD_FUNC_ARG;
1662 int CyaSSL_CTX_SetCRL_Cb(CYASSL_CTX* ctx, CbMissingCRL cb)
1664 CYASSL_ENTER("CyaSSL_CTX_SetCRL_Cb");
1666 return CyaSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
1668 return BAD_FUNC_ARG;
1672 #endif /* HAVE_CRL */
1675 #ifdef CYASSL_DER_LOAD
1677 /* Add format parameter to allow DER load of CA files */
1678 int CyaSSL_CTX_der_load_verify_locations(CYASSL_CTX* ctx, const char* file,
1681 CYASSL_ENTER("CyaSSL_CTX_der_load_verify_locations");
1682 if (ctx == NULL || file == NULL)
1685 if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
1691 #endif /* CYASSL_DER_LOAD */
1694 #ifdef CYASSL_CERT_GEN
1696 /* load pem cert from file into der buffer, return der size or error */
1697 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
1699 byte staticBuffer[FILE_BUFFER_SIZE];
1700 byte* fileBuf = staticBuffer;
1705 XFILE* file = XFOPEN(fileName, "rb");
1709 CYASSL_ENTER("CyaSSL_PemCertToDer");
1710 converted.buffer = 0;
1712 if (!file) return SSL_BAD_FILE;
1713 XFSEEK(file, 0, XSEEK_END);
1717 if (sz > (long)sizeof(staticBuffer)) {
1718 fileBuf = (byte*) XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
1719 if (fileBuf == NULL) {
1721 return SSL_BAD_FILE;
1726 if ( (ret = XFREAD(fileBuf, sz, 1, file)) < 0)
1729 ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, 0, &info, &ecc);
1732 if (converted.length < (word32)derSz) {
1733 XMEMCPY(derBuf, converted.buffer, converted.length);
1734 ret = converted.length;
1740 XFREE(converted.buffer, 0, DYNAMIC_TYPE_CA);
1742 XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
1748 #endif /* CYASSL_CERT_GEN */
1751 int CyaSSL_CTX_use_certificate_file(CYASSL_CTX* ctx, const char* file,
1754 CYASSL_ENTER("CyaSSL_CTX_use_certificate_file");
1755 if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
1762 int CyaSSL_CTX_use_PrivateKey_file(CYASSL_CTX* ctx, const char* file,int format)
1764 CYASSL_ENTER("CyaSSL_CTX_use_PrivateKey_file");
1765 if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL)
1773 int CyaSSL_CTX_use_certificate_chain_file(CYASSL_CTX* ctx, const char* file)
1775 /* procces up to MAX_CHAIN_DEPTH plus subject cert */
1776 CYASSL_ENTER("CyaSSL_CTX_use_certificate_chain_file");
1777 if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL)
1785 #ifdef OPENSSL_EXTRA
1786 /* put SSL type in extra for now, not very common */
1788 int CyaSSL_use_certificate_file(CYASSL* ssl, const char* file, int format)
1790 CYASSL_ENTER("CyaSSL_use_certificate_file");
1791 if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0, NULL)
1799 int CyaSSL_use_PrivateKey_file(CYASSL* ssl, const char* file, int format)
1801 CYASSL_ENTER("CyaSSL_use_PrivateKey_file");
1802 if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL)
1810 int CyaSSL_use_certificate_chain_file(CYASSL* ssl, const char* file)
1812 /* procces up to MAX_CHAIN_DEPTH plus subject cert */
1813 CYASSL_ENTER("CyaSSL_use_certificate_chain_file");
1814 if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1, NULL)
1822 /* server wrapper for ctx or ssl Diffie-Hellman parameters */
1823 static int CyaSSL_SetTmpDH_buffer_wrapper(CYASSL_CTX* ctx, CYASSL* ssl,
1824 const unsigned char* buf, long sz, int format)
1829 byte p[MAX_DH_SIZE];
1830 byte g[MAX_DH_SIZE];
1831 word32 pSz = sizeof(p);
1832 word32 gSz = sizeof(g);
1834 der.buffer = (byte*)buf;
1837 if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
1838 return SSL_BAD_FILETYPE;
1840 if (format == SSL_FILETYPE_PEM) {
1842 ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap, NULL,NULL);
1844 XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
1850 if (DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0)
1851 ret = SSL_BAD_FILETYPE;
1854 ret = CyaSSL_SetTmpDH(ssl, p, pSz, g, gSz);
1856 ret = CyaSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
1860 XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
1865 /* server Diffie-Hellman parameters */
1866 int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, const unsigned char* buf, long sz,
1869 return CyaSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
1873 /* server ctx Diffie-Hellman parameters */
1874 int CyaSSL_CTX_SetTmpDH_buffer(CYASSL_CTX* ctx, const unsigned char* buf,
1875 long sz, int format)
1877 return CyaSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
1883 /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
1884 int CyaSSL_CTX_SetTmpEC_DHE_Sz(CYASSL_CTX* ctx, word16 sz)
1886 if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
1887 return BAD_FUNC_ARG;
1889 ctx->eccTempKeySz = sz;
1895 /* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
1896 int CyaSSL_SetTmpEC_DHE_Sz(CYASSL* ssl, word16 sz)
1898 if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
1899 return BAD_FUNC_ARG;
1901 ssl->eccTempKeySz = sz;
1906 #endif /* HAVE_ECC */
1909 #if !defined(NO_FILESYSTEM)
1911 /* server Diffie-Hellman parameters */
1912 static int CyaSSL_SetTmpDH_file_wrapper(CYASSL_CTX* ctx, CYASSL* ssl,
1913 const char* fname, int format)
1915 byte staticBuffer[FILE_BUFFER_SIZE];
1916 byte* myBuffer = staticBuffer;
1920 XFILE* file = XFOPEN(fname, "rb");
1922 if (!file) return SSL_BAD_FILE;
1923 XFSEEK(file, 0, XSEEK_END);
1927 if (sz > (long)sizeof(staticBuffer)) {
1928 CYASSL_MSG("Getting dynamic buffer");
1929 myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
1930 if (myBuffer == NULL) {
1932 return SSL_BAD_FILE;
1937 if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0)
1941 ret = CyaSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
1943 ret = CyaSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
1947 if (dynamic) XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
1952 /* server Diffie-Hellman parameters */
1953 int CyaSSL_SetTmpDH_file(CYASSL* ssl, const char* fname, int format)
1955 return CyaSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
1959 /* server Diffie-Hellman parameters */
1960 int CyaSSL_CTX_SetTmpDH_file(CYASSL_CTX* ctx, const char* fname, int format)
1962 return CyaSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
1966 #endif /* !NO_FILESYSTEM */
1967 #endif /* OPENSSL_EXTRA */
1971 int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX* ctx, const char* file)
1973 CYASSL_ENTER("CyaSSL_CTX_use_NTRUPrivateKey_file");
1974 if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL)
1983 #endif /* HAVE_NTRU */
1987 #ifdef OPENSSL_EXTRA
1989 int CyaSSL_CTX_use_RSAPrivateKey_file(CYASSL_CTX* ctx,const char* file,
1992 CYASSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
1993 if (ProcessFile(ctx, file,format,PRIVATEKEY_TYPE,NULL,0, NULL)
2000 int CyaSSL_use_RSAPrivateKey_file(CYASSL* ssl, const char* file, int format)
2002 CYASSL_ENTER("CyaSSL_use_RSAPrivateKey_file");
2003 if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL)
2010 #endif /* OPENSSL_EXTRA */
2012 #endif /* NO_FILESYSTEM */
2015 void CyaSSL_CTX_set_verify(CYASSL_CTX* ctx, int mode, VerifyCallback vc)
2017 CYASSL_ENTER("CyaSSL_CTX_set_verify");
2018 if (mode & SSL_VERIFY_PEER) {
2019 ctx->verifyPeer = 1;
2020 ctx->verifyNone = 0; /* in case perviously set */
2023 if (mode == SSL_VERIFY_NONE) {
2024 ctx->verifyNone = 1;
2025 ctx->verifyPeer = 0; /* in case previously set */
2028 if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
2029 ctx->failNoCert = 1;
2031 ctx->verifyCallback = vc;
2035 void CyaSSL_set_verify(CYASSL* ssl, int mode, VerifyCallback vc)
2037 CYASSL_ENTER("CyaSSL_set_verify");
2038 if (mode & SSL_VERIFY_PEER) {
2039 ssl->options.verifyPeer = 1;
2040 ssl->options.verifyNone = 0; /* in case perviously set */
2043 if (mode == SSL_VERIFY_NONE) {
2044 ssl->options.verifyNone = 1;
2045 ssl->options.verifyPeer = 0; /* in case previously set */
2048 if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
2049 ssl->options.failNoCert = 1;
2051 ssl->verifyCallback = vc;
2055 /* store context CA Cache addition callback */
2056 void CyaSSL_CTX_SetCACb(CYASSL_CTX* ctx, CallbackCACache cb)
2059 ctx->cm->caCacheCallback = cb;
2063 #ifndef NO_SESSION_CACHE
2065 CYASSL_SESSION* CyaSSL_get_session(CYASSL* ssl)
2067 CYASSL_ENTER("SSL_get_session");
2069 return GetSession(ssl, 0);
2075 int CyaSSL_set_session(CYASSL* ssl, CYASSL_SESSION* session)
2077 CYASSL_ENTER("SSL_set_session");
2079 return SetSession(ssl, session);
2084 #endif /* NO_SESSION_CACHE */
2087 void CyaSSL_load_error_strings(void) /* compatibility only */
2091 int CyaSSL_library_init(void)
2093 CYASSL_ENTER("SSL_library_init");
2094 if (CyaSSL_Init() == 0)
2097 return SSL_FATAL_ERROR;
2101 #ifndef NO_SESSION_CACHE
2103 /* on by default if built in but allow user to turn off */
2104 long CyaSSL_CTX_set_session_cache_mode(CYASSL_CTX* ctx, long mode)
2106 CYASSL_ENTER("SSL_CTX_set_session_cache_mode");
2107 if (mode == SSL_SESS_CACHE_OFF)
2108 ctx->sessionCacheOff = 1;
2110 if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
2111 ctx->sessionCacheFlushOff = 1;
2116 #endif /* NO_SESSION_CACHE */
2119 int CyaSSL_CTX_set_cipher_list(CYASSL_CTX* ctx, const char* list)
2121 CYASSL_ENTER("CyaSSL_CTX_set_cipher_list");
2122 if (SetCipherList(&ctx->suites, list))
2129 int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list)
2131 CYASSL_ENTER("CyaSSL_set_cipher_list");
2132 if (SetCipherList(&ssl->suites, list)) {
2136 havePSK = ssl->options.havePSK;
2139 InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
2140 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
2141 ssl->options.haveStaticECC, ssl->options.side);
2150 /* client only parts */
2151 #ifndef NO_CYASSL_CLIENT
2153 CYASSL_METHOD* CyaSSLv3_client_method(void)
2155 CYASSL_METHOD* method =
2156 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
2157 DYNAMIC_TYPE_METHOD);
2158 CYASSL_ENTER("SSLv3_client_method");
2160 InitSSL_Method(method, MakeSSLv3());
2165 CYASSL_METHOD* CyaDTLSv1_client_method(void)
2167 CYASSL_METHOD* method =
2168 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
2169 DYNAMIC_TYPE_METHOD);
2170 CYASSL_ENTER("DTLSv1_client_method");
2172 InitSSL_Method(method, MakeDTLSv1());
2178 /* please see note at top of README if you get an error from connect */
2179 int CyaSSL_connect(CYASSL* ssl)
2183 CYASSL_ENTER("SSL_connect()");
2189 if (ssl->options.side != CLIENT_END) {
2190 CYASSL_ERROR(ssl->error = SIDE_ERROR);
2191 return SSL_FATAL_ERROR;
2195 if (ssl->version.major == DTLS_MAJOR &&
2196 ssl->version.minor == DTLS_MINOR) {
2197 ssl->options.dtls = 1;
2198 ssl->options.tls = 1;
2199 ssl->options.tls1_1 = 1;
2203 if (ssl->buffers.outputBuffer.length > 0) {
2204 if ( (ssl->error = SendBuffered(ssl)) == 0) {
2205 ssl->options.connectState++;
2206 CYASSL_MSG("connect state: Advanced from buffered send");
2209 CYASSL_ERROR(ssl->error);
2210 return SSL_FATAL_ERROR;
2214 switch (ssl->options.connectState) {
2216 case CONNECT_BEGIN :
2217 /* always send client hello first */
2218 if ( (ssl->error = SendClientHello(ssl)) != 0) {
2219 CYASSL_ERROR(ssl->error);
2220 return SSL_FATAL_ERROR;
2222 ssl->options.connectState = CLIENT_HELLO_SENT;
2223 CYASSL_MSG("connect state: CLIENT_HELLO_SENT");
2225 case CLIENT_HELLO_SENT :
2226 neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
2227 SERVER_HELLODONE_COMPLETE;
2229 if (ssl->options.dtls && !ssl->options.resuming)
2230 neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
2233 while (ssl->options.serverState < neededState) {
2234 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2235 CYASSL_ERROR(ssl->error);
2236 return SSL_FATAL_ERROR;
2238 /* if resumption failed, reset needed state */
2239 else if (neededState == SERVER_FINISHED_COMPLETE)
2240 if (!ssl->options.resuming) {
2241 if (!ssl->options.dtls)
2242 neededState = SERVER_HELLODONE_COMPLETE;
2244 neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
2248 ssl->options.connectState = HELLO_AGAIN;
2249 CYASSL_MSG("connect state: HELLO_AGAIN");
2252 if (ssl->options.certOnly)
2256 if (ssl->options.dtls && !ssl->options.resuming) {
2257 /* re-init hashes, exclude first hello and verify request */
2258 InitMd5(&ssl->hashMd5);
2259 InitSha(&ssl->hashSha);
2261 if (IsAtLeastTLSv1_2(ssl))
2262 InitSha256(&ssl->hashSha256);
2264 if ( (ssl->error = SendClientHello(ssl)) != 0) {
2265 CYASSL_ERROR(ssl->error);
2266 return SSL_FATAL_ERROR;
2271 ssl->options.connectState = HELLO_AGAIN_REPLY;
2272 CYASSL_MSG("connect state: HELLO_AGAIN_REPLY");
2274 case HELLO_AGAIN_REPLY :
2276 if (ssl->options.dtls) {
2277 neededState = ssl->options.resuming ?
2278 SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
2281 while (ssl->options.serverState < neededState) {
2282 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2283 CYASSL_ERROR(ssl->error);
2284 return SSL_FATAL_ERROR;
2286 /* if resumption failed, reset needed state */
2287 else if (neededState == SERVER_FINISHED_COMPLETE)
2288 if (!ssl->options.resuming)
2289 neededState = SERVER_HELLODONE_COMPLETE;
2294 ssl->options.connectState = FIRST_REPLY_DONE;
2295 CYASSL_MSG("connect state: FIRST_REPLY_DONE");
2297 case FIRST_REPLY_DONE :
2298 if (ssl->options.sendVerify)
2299 if ( (ssl->error = SendCertificate(ssl)) != 0) {
2300 CYASSL_ERROR(ssl->error);
2301 return SSL_FATAL_ERROR;
2304 ssl->options.connectState = FIRST_REPLY_FIRST;
2305 CYASSL_MSG("connect state: FIRST_REPLY_FIRST");
2307 case FIRST_REPLY_FIRST :
2308 if (!ssl->options.resuming)
2309 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
2310 CYASSL_ERROR(ssl->error);
2311 return SSL_FATAL_ERROR;
2314 ssl->options.connectState = FIRST_REPLY_SECOND;
2315 CYASSL_MSG("connect state: FIRST_REPLY_SECOND");
2317 case FIRST_REPLY_SECOND :
2318 if (ssl->options.sendVerify)
2319 if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
2320 CYASSL_ERROR(ssl->error);
2321 return SSL_FATAL_ERROR;
2323 ssl->options.connectState = FIRST_REPLY_THIRD;
2324 CYASSL_MSG("connect state: FIRST_REPLY_THIRD");
2326 case FIRST_REPLY_THIRD :
2327 if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
2328 CYASSL_ERROR(ssl->error);
2329 return SSL_FATAL_ERROR;
2331 ssl->options.connectState = FIRST_REPLY_FOURTH;
2332 CYASSL_MSG("connect state: FIRST_REPLY_FOURTH");
2334 case FIRST_REPLY_FOURTH :
2335 if ( (ssl->error = SendFinished(ssl)) != 0) {
2336 CYASSL_ERROR(ssl->error);
2337 return SSL_FATAL_ERROR;
2340 ssl->options.connectState = FINISHED_DONE;
2341 CYASSL_MSG("connect state: FINISHED_DONE");
2343 case FINISHED_DONE :
2345 while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
2346 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2347 CYASSL_ERROR(ssl->error);
2348 return SSL_FATAL_ERROR;
2351 ssl->options.connectState = SECOND_REPLY_DONE;
2352 CYASSL_MSG("connect state: SECOND_REPLY_DONE");
2354 case SECOND_REPLY_DONE:
2355 if (ssl->buffers.inputBuffer.dynamicFlag)
2356 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
2357 CYASSL_LEAVE("SSL_connect()", SSL_SUCCESS);
2361 CYASSL_MSG("Unknown connect state ERROR");
2362 return SSL_FATAL_ERROR; /* unknown connect state */
2366 #endif /* NO_CYASSL_CLIENT */
2369 /* server only parts */
2370 #ifndef NO_CYASSL_SERVER
2372 CYASSL_METHOD* CyaSSLv3_server_method(void)
2374 CYASSL_METHOD* method =
2375 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
2376 DYNAMIC_TYPE_METHOD);
2377 CYASSL_ENTER("SSLv3_server_method");
2379 InitSSL_Method(method, MakeSSLv3());
2380 method->side = SERVER_END;
2387 CYASSL_METHOD* CyaDTLSv1_server_method(void)
2389 CYASSL_METHOD* method =
2390 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
2391 DYNAMIC_TYPE_METHOD);
2392 CYASSL_ENTER("DTLSv1_server_method");
2394 InitSSL_Method(method, MakeDTLSv1());
2395 method->side = SERVER_END;
2402 int CyaSSL_accept(CYASSL* ssl)
2405 CYASSL_ENTER("SSL_accept()");
2412 havePSK = ssl->options.havePSK;
2415 if (ssl->options.side != SERVER_END) {
2416 CYASSL_ERROR(ssl->error = SIDE_ERROR);
2417 return SSL_FATAL_ERROR;
2420 /* in case used set_accept_state after init */
2421 if (!havePSK && (ssl->buffers.certificate.buffer == NULL ||
2422 ssl->buffers.key.buffer == NULL)) {
2423 CYASSL_MSG("accept error: don't have server cert and key");
2424 ssl->error = NO_PRIVATE_KEY;
2425 CYASSL_ERROR(ssl->error);
2426 return SSL_FATAL_ERROR;
2430 /* in case used set_accept_state after init */
2431 if (ssl->eccTempKeyPresent == 0) {
2432 if (ecc_make_key(&ssl->rng, ssl->eccTempKeySz,
2433 &ssl->eccTempKey) != 0) {
2434 ssl->error = ECC_MAKEKEY_ERROR;
2435 CYASSL_ERROR(ssl->error);
2436 return SSL_FATAL_ERROR;
2438 ssl->eccTempKeyPresent = 1;
2443 if (ssl->version.major == DTLS_MAJOR &&
2444 ssl->version.minor == DTLS_MINOR) {
2445 ssl->options.dtls = 1;
2446 ssl->options.tls = 1;
2447 ssl->options.tls1_1 = 1;
2451 if (ssl->buffers.outputBuffer.length > 0) {
2452 if ( (ssl->error = SendBuffered(ssl)) == 0) {
2453 ssl->options.acceptState++;
2454 CYASSL_MSG("accept state: Advanced from buffered send");
2457 CYASSL_ERROR(ssl->error);
2458 return SSL_FATAL_ERROR;
2462 switch (ssl->options.acceptState) {
2466 while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
2467 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2468 CYASSL_ERROR(ssl->error);
2469 return SSL_FATAL_ERROR;
2471 ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
2472 CYASSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
2474 case ACCEPT_CLIENT_HELLO_DONE :
2476 if (ssl->options.dtls && !ssl->options.resuming)
2477 if ( (ssl->error = SendHelloVerifyRequest(ssl)) != 0) {
2478 CYASSL_ERROR(ssl->error);
2479 return SSL_FATAL_ERROR;
2482 ssl->options.acceptState = HELLO_VERIFY_SENT;
2483 CYASSL_MSG("accept state HELLO_VERIFY_SENT");
2485 case HELLO_VERIFY_SENT:
2487 if (ssl->options.dtls && !ssl->options.resuming) {
2488 ssl->options.clientState = NULL_STATE; /* get again */
2489 /* re-init hashes, exclude first hello and verify request */
2490 InitMd5(&ssl->hashMd5);
2491 InitSha(&ssl->hashSha);
2493 if (IsAtLeastTLSv1_2(ssl))
2494 InitSha256(&ssl->hashSha256);
2497 while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
2498 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2499 CYASSL_ERROR(ssl->error);
2500 return SSL_FATAL_ERROR;
2504 ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
2505 CYASSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
2507 case ACCEPT_FIRST_REPLY_DONE :
2508 if ( (ssl->error = SendServerHello(ssl)) != 0) {
2509 CYASSL_ERROR(ssl->error);
2510 return SSL_FATAL_ERROR;
2512 ssl->options.acceptState = SERVER_HELLO_SENT;
2513 CYASSL_MSG("accept state SERVER_HELLO_SENT");
2515 case SERVER_HELLO_SENT :
2516 if (!ssl->options.resuming)
2517 if ( (ssl->error = SendCertificate(ssl)) != 0) {
2518 CYASSL_ERROR(ssl->error);
2519 return SSL_FATAL_ERROR;
2521 ssl->options.acceptState = CERT_SENT;
2522 CYASSL_MSG("accept state CERT_SENT");
2525 if (!ssl->options.resuming)
2526 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
2527 CYASSL_ERROR(ssl->error);
2528 return SSL_FATAL_ERROR;
2530 ssl->options.acceptState = KEY_EXCHANGE_SENT;
2531 CYASSL_MSG("accept state KEY_EXCHANGE_SENT");
2533 case KEY_EXCHANGE_SENT :
2534 if (!ssl->options.resuming)
2535 if (ssl->options.verifyPeer)
2536 if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
2537 CYASSL_ERROR(ssl->error);
2538 return SSL_FATAL_ERROR;
2540 ssl->options.acceptState = CERT_REQ_SENT;
2541 CYASSL_MSG("accept state CERT_REQ_SENT");
2543 case CERT_REQ_SENT :
2544 if (!ssl->options.resuming)
2545 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
2546 CYASSL_ERROR(ssl->error);
2547 return SSL_FATAL_ERROR;
2549 ssl->options.acceptState = SERVER_HELLO_DONE;
2550 CYASSL_MSG("accept state SERVER_HELLO_DONE");
2552 case SERVER_HELLO_DONE :
2553 if (!ssl->options.resuming) {
2554 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
2555 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2556 CYASSL_ERROR(ssl->error);
2557 return SSL_FATAL_ERROR;
2560 ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
2561 CYASSL_MSG("accept state ACCEPT_SECOND_REPLY_DONE");
2563 case ACCEPT_SECOND_REPLY_DONE :
2564 if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
2565 CYASSL_ERROR(ssl->error);
2566 return SSL_FATAL_ERROR;
2568 ssl->options.acceptState = CHANGE_CIPHER_SENT;
2569 CYASSL_MSG("accept state CHANGE_CIPHER_SENT");
2571 case CHANGE_CIPHER_SENT :
2572 if ( (ssl->error = SendFinished(ssl)) != 0) {
2573 CYASSL_ERROR(ssl->error);
2574 return SSL_FATAL_ERROR;
2577 ssl->options.acceptState = ACCEPT_FINISHED_DONE;
2578 CYASSL_MSG("accept state ACCEPT_FINISHED_DONE");
2580 case ACCEPT_FINISHED_DONE :
2581 if (ssl->options.resuming)
2582 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
2583 if ( (ssl->error = ProcessReply(ssl)) < 0) {
2584 CYASSL_ERROR(ssl->error);
2585 return SSL_FATAL_ERROR;
2588 ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
2589 CYASSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
2591 case ACCEPT_THIRD_REPLY_DONE :
2592 if (ssl->buffers.inputBuffer.dynamicFlag)
2593 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
2594 CYASSL_LEAVE("SSL_accept()", SSL_SUCCESS);
2598 CYASSL_MSG("Unknown accept state ERROR");
2599 return SSL_FATAL_ERROR;
2603 #endif /* NO_CYASSL_SERVER */
2605 /* prevent multiple mutex initializations */
2606 static volatile int initRefCount = 0;
2607 static CyaSSL_Mutex count_mutex; /* init ref count mutex */
2609 int CyaSSL_Init(void)
2613 CYASSL_ENTER("CyaSSL_Init");
2615 if (initRefCount == 0) {
2616 #ifndef NO_SESSION_CACHE
2617 if (InitMutex(&session_mutex) != 0)
2618 ret = BAD_MUTEX_ERROR;
2620 if (InitMutex(&count_mutex) != 0)
2621 ret = BAD_MUTEX_ERROR;
2624 LockMutex(&count_mutex);
2626 UnLockMutex(&count_mutex);
2633 int CyaSSL_Cleanup(void)
2638 CYASSL_ENTER("CyaSSL_Cleanup");
2640 LockMutex(&count_mutex);
2642 release = initRefCount-- == 1;
2643 if (initRefCount < 0)
2646 UnLockMutex(&count_mutex);
2651 #ifndef NO_SESSION_CACHE
2652 if (FreeMutex(&session_mutex) != 0)
2653 ret = BAD_MUTEX_ERROR;
2655 if (FreeMutex(&count_mutex) != 0)
2656 ret = BAD_MUTEX_ERROR;
2662 #ifndef NO_SESSION_CACHE
2665 static INLINE word32 HashSession(const byte* sessionID)
2667 /* id is random, just make 32 bit number from first 4 bytes for now */
2668 return (sessionID[0] << 24) | (sessionID[1] << 16) | (sessionID[2] << 8) |
2673 void CyaSSL_flush_sessions(CYASSL_CTX* ctx, long tm)
2675 /* static table now, no flusing needed */
2681 /* set ssl session timeout in seconds */
2682 int CyaSSL_set_timeout(CYASSL* ssl, unsigned int to)
2685 return BAD_FUNC_ARG;
2693 /* set ctx session timeout in seconds */
2694 int CyaSSL_CTX_set_timeout(CYASSL_CTX* ctx, unsigned int to)
2697 return BAD_FUNC_ARG;
2705 CYASSL_SESSION* GetSession(CYASSL* ssl, byte* masterSecret)
2707 CYASSL_SESSION* ret = 0;
2708 const byte* id = ssl->arrays.sessionID;
2712 if (ssl->options.sessionCacheOff)
2715 if (ssl->options.haveSessionId == 0)
2718 row = HashSession(id) % SESSION_ROWS;
2720 if (LockMutex(&session_mutex) != 0)
2723 if (SessionCache[row].totalCount >= SESSIONS_PER_ROW)
2724 idx = SESSIONS_PER_ROW - 1;
2726 idx = SessionCache[row].nextIdx - 1;
2728 for (; idx >= 0; idx--) {
2729 CYASSL_SESSION* current;
2731 if (idx >= SESSIONS_PER_ROW) /* server could have restarted, idx */
2732 break; /* would be word32(-1) and seg fault */
2734 current = &SessionCache[row].Sessions[idx];
2735 if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
2736 if (LowResTimer() < (current->bornOn + current->timeout)) {
2739 XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
2745 UnLockMutex(&session_mutex);
2751 int SetSession(CYASSL* ssl, CYASSL_SESSION* session)
2753 if (ssl->options.sessionCacheOff)
2756 if (LowResTimer() < (session->bornOn + session->timeout)) {
2757 ssl->session = *session;
2758 ssl->options.resuming = 1;
2760 #ifdef SESSION_CERTS
2761 ssl->version = session->version;
2762 ssl->options.cipherSuite0 = session->cipherSuite0;
2763 ssl->options.cipherSuite = session->cipherSuite;
2768 return SSL_FAILURE; /* session timed out */
2772 int AddSession(CYASSL* ssl)
2776 if (ssl->options.sessionCacheOff)
2779 if (ssl->options.haveSessionId == 0)
2782 row = HashSession(ssl->arrays.sessionID) % SESSION_ROWS;
2784 if (LockMutex(&session_mutex) != 0)
2785 return BAD_MUTEX_ERROR;
2787 idx = SessionCache[row].nextIdx++;
2789 XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
2790 ssl->arrays.masterSecret, SECRET_LEN);
2791 XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays.sessionID,
2794 SessionCache[row].Sessions[idx].timeout = ssl->timeout;
2795 SessionCache[row].Sessions[idx].bornOn = LowResTimer();
2797 #ifdef SESSION_CERTS
2798 SessionCache[row].Sessions[idx].chain.count = ssl->session.chain.count;
2799 XMEMCPY(SessionCache[row].Sessions[idx].chain.certs,
2800 ssl->session.chain.certs, sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
2802 SessionCache[row].Sessions[idx].version = ssl->version;
2803 SessionCache[row].Sessions[idx].cipherSuite0 = ssl->options.cipherSuite0;
2804 SessionCache[row].Sessions[idx].cipherSuite = ssl->options.cipherSuite;
2807 SessionCache[row].totalCount++;
2808 if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
2809 SessionCache[row].nextIdx = 0;
2811 if (UnLockMutex(&session_mutex) != 0)
2812 return BAD_MUTEX_ERROR;
2818 #ifdef SESSION_STATS
2821 void PrintSessionStats(void)
2823 word32 totalSessionsSeen = 0;
2824 word32 totalSessionsNow = 0;
2827 double E; /* expected freq */
2828 double chiSquare = 0;
2830 for (i = 0; i < SESSION_ROWS; i++) {
2831 totalSessionsSeen += SessionCache[i].totalCount;
2833 if (SessionCache[i].totalCount >= SESSIONS_PER_ROW)
2834 rowNow = SESSIONS_PER_ROW;
2835 else if (SessionCache[i].nextIdx == 0)
2838 rowNow = SessionCache[i].nextIdx;
2840 totalSessionsNow += rowNow;
2843 printf("Total Sessions Seen = %d\n", totalSessionsSeen);
2844 printf("Total Sessions Now = %d\n", totalSessionsNow);
2846 E = (double)totalSessionsSeen / SESSION_ROWS;
2848 for (i = 0; i < SESSION_ROWS; i++) {
2849 double diff = SessionCache[i].totalCount - E;
2850 diff *= diff; /* square */
2851 diff /= E; /* normalize */
2855 printf(" chi-square = %5.1f, d.f. = %d\n", chiSquare,
2857 if (SESSION_ROWS == 11)
2858 printf(" .05 p value = 18.3, chi-square should be less\n");
2859 else if (SESSION_ROWS == 211)
2860 printf(".05 p value = 244.8, chi-square should be less\n");
2861 else if (SESSION_ROWS == 5981)
2862 printf(".05 p value = 6161.0, chi-square should be less\n");
2863 else if (SESSION_ROWS == 3)
2864 printf(".05 p value = 6.0, chi-square should be less\n");
2865 else if (SESSION_ROWS == 2861)
2866 printf(".05 p value = 2985.5, chi-square should be less\n");
2870 #endif /* SESSION_STATS */
2872 #else /* NO_SESSION_CACHE */
2874 /* No session cache version */
2875 CYASSL_SESSION* GetSession(CYASSL* ssl, byte* masterSecret)
2880 #endif /* NO_SESSION_CACHE */
2883 /* call before SSL_connect, if verifying will add name check to
2884 date check and signature check */
2885 int CyaSSL_check_domain_name(CYASSL* ssl, const char* dn)
2887 CYASSL_ENTER("CyaSSL_check_domain_name");
2888 if (ssl->buffers.domainName.buffer)
2889 XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
2891 ssl->buffers.domainName.length = (word32)XSTRLEN(dn) + 1;
2892 ssl->buffers.domainName.buffer = (byte*) XMALLOC(
2893 ssl->buffers.domainName.length, ssl->heap, DYNAMIC_TYPE_DOMAIN);
2895 if (ssl->buffers.domainName.buffer) {
2896 XSTRNCPY((char*)ssl->buffers.domainName.buffer, dn,
2897 ssl->buffers.domainName.length);
2901 ssl->error = MEMORY_ERROR;
2907 /* turn on CyaSSL zlib compression
2908 returns 0 for success, else error (not built in)
2910 int CyaSSL_set_compression(CYASSL* ssl)
2912 CYASSL_ENTER("CyaSSL_set_compression");
2915 ssl->options.usingCompression = 1;
2918 return NOT_COMPILED_IN;
2923 #ifndef USE_WINDOWS_API
2926 /* simulate writev semantics, doesn't actually do block at a time though
2927 because of SSL_write behavior and because front adds may be small */
2928 int CyaSSL_writev(CYASSL* ssl, const struct iovec* iov, int iovcnt)
2930 byte tmp[OUTPUT_RECORD_SIZE];
2931 byte* myBuffer = tmp;
2938 CYASSL_ENTER("CyaSSL_writev");
2940 for (i = 0; i < iovcnt; i++)
2941 send += iov[i].iov_len;
2943 if (send > (int)sizeof(tmp)) {
2944 byte* tmp2 = (byte*) XMALLOC(send, ssl->heap,
2945 DYNAMIC_TYPE_WRITEV);
2947 return MEMORY_ERROR;
2952 for (i = 0; i < iovcnt; i++) {
2953 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
2954 idx += iov[i].iov_len;
2957 ret = CyaSSL_write(ssl, myBuffer, send);
2959 if (newBuffer) XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
2967 #ifdef CYASSL_CALLBACKS
2969 typedef struct itimerval Itimerval;
2971 /* don't keep calling simple functions while setting up timer and singals
2972 if no inlining these are the next best */
2974 #define AddTimes(a, b, c) \
2976 c.tv_sec = a.tv_sec + b.tv_sec; \
2977 c.tv_usec = a.tv_usec + b.tv_usec; \
2978 if (c.tv_sec >= 1000000) { \
2980 c.tv_usec -= 1000000; \
2985 #define SubtractTimes(a, b, c) \
2987 c.tv_sec = a.tv_sec - b.tv_sec; \
2988 c.tv_usec = a.tv_usec - b.tv_usec; \
2989 if (c.tv_sec < 0) { \
2991 c.tv_usec += 1000000; \
2995 #define CmpTimes(a, b, cmp) \
2996 ((a.tv_sec == b.tv_sec) ? \
2997 (a.tv_usec cmp b.tv_usec) : \
2998 (a.tv_sec cmp b.tv_sec)) \
3001 /* do nothing handler */
3002 static void myHandler(int signo)
3008 static int CyaSSL_ex_wrapper(CYASSL* ssl, HandShakeCallBack hsCb,
3009 TimeoutCallBack toCb, Timeval timeout)
3011 int ret = SSL_FATAL_ERROR;
3012 int oldTimerOn = 0; /* was timer already on */
3016 Itimerval myTimeout;
3017 Itimerval oldTimeout; /* if old timer adjust from total time to reset */
3018 struct sigaction act, oact;
3020 #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
3024 InitHandShakeInfo(&ssl->handShakeInfo);
3028 InitTimeoutInfo(&ssl->timeoutInfo);
3030 if (gettimeofday(&startTime, 0) < 0)
3031 ERR_OUT(GETTIME_ERROR);
3033 /* use setitimer to simulate getitimer, init 0 myTimeout */
3034 myTimeout.it_interval.tv_sec = 0;
3035 myTimeout.it_interval.tv_usec = 0;
3036 myTimeout.it_value.tv_sec = 0;
3037 myTimeout.it_value.tv_usec = 0;
3038 if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
3039 ERR_OUT(SETITIMER_ERROR);
3041 if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
3044 /* is old timer going to expire before ours */
3045 if (CmpTimes(oldTimeout.it_value, timeout, <)) {
3046 timeout.tv_sec = oldTimeout.it_value.tv_sec;
3047 timeout.tv_usec = oldTimeout.it_value.tv_usec;
3050 myTimeout.it_value.tv_sec = timeout.tv_sec;
3051 myTimeout.it_value.tv_usec = timeout.tv_usec;
3053 /* set up signal handler, don't restart socket send/recv */
3054 act.sa_handler = myHandler;
3055 sigemptyset(&act.sa_mask);
3058 act.sa_flags |= SA_INTERRUPT;
3060 if (sigaction(SIGALRM, &act, &oact) < 0)
3061 ERR_OUT(SIGACT_ERROR);
3063 if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
3064 ERR_OUT(SETITIMER_ERROR);
3068 #ifndef NO_CYASSL_CLIENT
3069 if (ssl->options.side == CLIENT_END)
3070 ret = CyaSSL_connect(ssl);
3072 #ifndef NO_CYASSL_SERVER
3073 if (ssl->options.side == SERVER_END)
3074 ret = CyaSSL_accept(ssl);
3080 gettimeofday(&endTime, 0);
3081 SubtractTimes(endTime, startTime, totalTime);
3082 /* adjust old timer for elapsed time */
3083 if (CmpTimes(totalTime, oldTimeout.it_value, <))
3084 SubtractTimes(oldTimeout.it_value, totalTime,
3085 oldTimeout.it_value);
3087 /* reset value to interval, may be off */
3088 oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
3089 oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
3091 /* keep iter the same whether there or not */
3093 /* restore old handler */
3094 if (sigaction(SIGALRM, &oact, 0) < 0)
3095 ret = SIGACT_ERROR; /* more pressing error, stomp */
3097 /* use old settings which may turn off (expired or not there) */
3098 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
3099 ret = SETITIMER_ERROR;
3101 /* if we had a timeout call callback */
3102 if (ssl->timeoutInfo.timeoutName[0]) {
3103 ssl->timeoutInfo.timeoutValue.tv_sec = timeout.tv_sec;
3104 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
3105 (toCb)(&ssl->timeoutInfo);
3108 FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
3112 FinishHandShakeInfo(&ssl->handShakeInfo, ssl);
3113 (hsCb)(&ssl->handShakeInfo);
3120 #ifndef NO_CYASSL_CLIENT
3122 int CyaSSL_connect_ex(CYASSL* ssl, HandShakeCallBack hsCb,
3123 TimeoutCallBack toCb, Timeval timeout)
3125 CYASSL_ENTER("CyaSSL_connect_ex");
3126 return CyaSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
3132 #ifndef NO_CYASSL_SERVER
3134 int CyaSSL_accept_ex(CYASSL* ssl, HandShakeCallBack hsCb,
3135 TimeoutCallBack toCb,Timeval timeout)
3137 CYASSL_ENTER("CyaSSL_accept_ex");
3138 return CyaSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
3143 #endif /* CYASSL_CALLBACKS */
3148 void CyaSSL_CTX_set_psk_client_callback(CYASSL_CTX* ctx,
3149 psk_client_callback cb)
3151 CYASSL_ENTER("SSL_CTX_set_psk_client_callback");
3153 ctx->client_psk_cb = cb;
3157 void CyaSSL_set_psk_client_callback(CYASSL* ssl, psk_client_callback cb)
3159 CYASSL_ENTER("SSL_set_psk_client_callback");
3160 ssl->options.havePSK = 1;
3161 ssl->options.client_psk_cb = cb;
3163 InitSuites(&ssl->suites, ssl->version,TRUE,TRUE, ssl->options.haveNTRU,
3164 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
3169 void CyaSSL_CTX_set_psk_server_callback(CYASSL_CTX* ctx,
3170 psk_server_callback cb)
3172 CYASSL_ENTER("SSL_CTX_set_psk_server_callback");
3174 ctx->server_psk_cb = cb;
3178 void CyaSSL_set_psk_server_callback(CYASSL* ssl, psk_server_callback cb)
3180 CYASSL_ENTER("SSL_set_psk_server_callback");
3181 ssl->options.havePSK = 1;
3182 ssl->options.server_psk_cb = cb;
3184 InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, TRUE,
3185 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
3186 ssl->options.haveStaticECC, ssl->options.side);
3190 const char* CyaSSL_get_psk_identity_hint(const CYASSL* ssl)
3192 CYASSL_ENTER("SSL_get_psk_identity_hint");
3193 return ssl->arrays.server_hint;
3197 const char* CyaSSL_get_psk_identity(const CYASSL* ssl)
3199 CYASSL_ENTER("SSL_get_psk_identity");
3200 return ssl->arrays.client_identity;
3204 int CyaSSL_CTX_use_psk_identity_hint(CYASSL_CTX* ctx, const char* hint)
3206 CYASSL_ENTER("SSL_CTX_use_psk_identity_hint");
3208 ctx->server_hint[0] = 0;
3210 XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
3211 ctx->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
3217 int CyaSSL_use_psk_identity_hint(CYASSL* ssl, const char* hint)
3219 CYASSL_ENTER("SSL_use_psk_identity_hint");
3221 ssl->arrays.server_hint[0] = 0;
3223 XSTRNCPY(ssl->arrays.server_hint, hint, MAX_PSK_ID_LEN);
3224 ssl->arrays.server_hint[MAX_PSK_ID_LEN - 1] = '\0';
3232 /* used to be defined on NO_FILESYSTEM only, but are generally useful */
3234 /* CyaSSL extension allows DER files to be loaded from buffers as well */
3235 int CyaSSL_CTX_load_verify_buffer(CYASSL_CTX* ctx, const unsigned char* in,
3236 long sz, int format)
3238 CYASSL_ENTER("CyaSSL_CTX_load_verify_buffer");
3239 if (format == SSL_FILETYPE_PEM)
3240 return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL);
3242 return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL,NULL,0);
3246 int CyaSSL_CTX_use_certificate_buffer(CYASSL_CTX* ctx,
3247 const unsigned char* in, long sz, int format)
3249 CYASSL_ENTER("CyaSSL_CTX_use_certificate_buffer");
3250 return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0);
3254 int CyaSSL_CTX_use_PrivateKey_buffer(CYASSL_CTX* ctx,
3255 const unsigned char* in, long sz, int format)
3257 CYASSL_ENTER("CyaSSL_CTX_use_PrivateKey_buffer");
3258 return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
3262 int CyaSSL_CTX_use_certificate_chain_buffer(CYASSL_CTX* ctx,
3263 const unsigned char* in, long sz)
3265 CYASSL_ENTER("CyaSSL_CTX_use_certificate_chain_buffer");
3266 return ProcessBuffer(ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE, NULL,
3270 int CyaSSL_use_certificate_buffer(CYASSL* ssl,
3271 const unsigned char* in, long sz, int format)
3273 CYASSL_ENTER("CyaSSL_use_certificate_buffer");
3274 return ProcessBuffer(ssl->ctx, in, sz, format,CERT_TYPE,ssl,NULL,0);
3278 int CyaSSL_use_PrivateKey_buffer(CYASSL* ssl,
3279 const unsigned char* in, long sz, int format)
3281 CYASSL_ENTER("CyaSSL_use_PrivateKey_buffer");
3282 return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
3287 int CyaSSL_use_certificate_chain_buffer(CYASSL* ssl,
3288 const unsigned char* in, long sz)
3290 CYASSL_ENTER("CyaSSL_use_certificate_chain_buffer");
3291 return ProcessBuffer(ssl->ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE,
3295 /* old NO_FILESYSTEM end */
3298 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
3301 int CyaSSL_add_all_algorithms(void)
3303 CYASSL_ENTER("CyaSSL_add_all_algorithms");
3309 long CyaSSL_CTX_sess_set_cache_size(CYASSL_CTX* ctx, long sz)
3311 /* cache size fixed at compile time in CyaSSL */
3318 void CyaSSL_CTX_set_quiet_shutdown(CYASSL_CTX* ctx, int mode)
3320 CYASSL_ENTER("CyaSSL_CTX_set_quiet_shutdown");
3322 ctx->quietShutdown = 1;
3326 void CyaSSL_set_quiet_shutdown(CYASSL* ssl, int mode)
3328 CYASSL_ENTER("CyaSSL_CTX_set_quiet_shutdown");
3330 ssl->options.quietShutdown = 1;
3334 void CyaSSL_set_bio(CYASSL* ssl, CYASSL_BIO* rd, CYASSL_BIO* wr)
3336 CYASSL_ENTER("SSL_set_bio");
3337 CyaSSL_set_rfd(ssl, rd->fd);
3338 CyaSSL_set_wfd(ssl, wr->fd);
3345 void CyaSSL_CTX_set_client_CA_list(CYASSL_CTX* ctx,
3346 STACK_OF(CYASSL_X509_NAME)* names)
3353 STACK_OF(CYASSL_X509_NAME)* CyaSSL_load_client_CA_file(const char* fname)
3360 int CyaSSL_CTX_set_default_verify_paths(CYASSL_CTX* ctx)
3362 /* TODO:, not needed in goahead */
3364 return SSL_NOT_IMPLEMENTED;
3368 /* keyblock size in bytes or -1 */
3369 int CyaSSL_get_keyblock_size(CYASSL* ssl)
3374 return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
3375 ssl->specs.hash_size);
3379 /* store keys returns 0 or -1 on error */
3380 int CyaSSL_get_keys(CYASSL* ssl, unsigned char** ms, unsigned int* msLen,
3381 unsigned char** sr, unsigned int* srLen,
3382 unsigned char** cr, unsigned int* crLen)
3387 *ms = ssl->arrays.masterSecret;
3388 *sr = ssl->arrays.serverRandom;
3389 *cr = ssl->arrays.clientRandom;
3391 *msLen = SECRET_LEN;
3399 void CyaSSL_set_accept_state(CYASSL* ssl)
3403 CYASSL_ENTER("SSL_set_accept_state");
3404 ssl->options.side = SERVER_END;
3405 /* reset suites in case user switched */
3407 havePSK = ssl->options.havePSK;
3409 InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
3410 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
3411 ssl->options.haveStaticECC, ssl->options.side);
3415 /* return true if connection established */
3416 int CyaSSL_is_init_finished(CYASSL* ssl)
3421 if (ssl->options.handShakeState == HANDSHAKE_DONE)
3428 void CyaSSL_CTX_set_tmp_rsa_callback(CYASSL_CTX* ctx,
3429 CYASSL_RSA*(*f)(CYASSL*, int, int))
3431 /* CyaSSL verifies all these internally */
3437 void CyaSSL_set_shutdown(CYASSL* ssl, int opt)
3444 long CyaSSL_CTX_set_options(CYASSL_CTX* ctx, long opt)
3446 /* goahead calls with 0, do nothing */
3447 CYASSL_ENTER("SSL_CTX_set_options");
3453 int CyaSSL_set_rfd(CYASSL* ssl, int rfd)
3455 CYASSL_ENTER("SSL_set_rfd");
3456 ssl->rfd = rfd; /* not used directly to allow IO callbacks */
3458 ssl->IOCB_ReadCtx = &ssl->rfd;
3464 int CyaSSL_set_wfd(CYASSL* ssl, int wfd)
3466 CYASSL_ENTER("SSL_set_wfd");
3467 ssl->wfd = wfd; /* not used directly to allow IO callbacks */
3469 ssl->IOCB_WriteCtx = &ssl->wfd;
3475 CYASSL_RSA* CyaSSL_RSA_generate_key(int len, unsigned long bits,
3476 void(*f)(int, int, void*), void* data)
3478 /* no tmp key needed, actual generation not supported */
3479 CYASSL_ENTER("RSA_generate_key");
3488 /* return the next, if any, altname from the peer cert */
3489 char* CyaSSL_X509_get_next_altname(CYASSL_X509* cert)
3492 CYASSL_ENTER("CyaSSL_X509_get_next_altname");
3494 /* don't have any to work with */
3495 if (cert == NULL || cert->altNames == NULL)
3498 /* already went through them */
3499 if (cert->altNamesNext == NULL)
3502 ret = cert->altNamesNext->name;
3503 cert->altNamesNext = cert->altNamesNext->next;
3509 CYASSL_X509_NAME* CyaSSL_X509_get_issuer_name(CYASSL_X509* cert)
3511 CYASSL_ENTER("X509_get_issuer_name");
3512 return &cert->issuer;
3516 CYASSL_X509_NAME* CyaSSL_X509_get_subject_name(CYASSL_X509* cert)
3518 CYASSL_ENTER("X509_get_subject_name");
3519 return &cert->subject;
3523 /* copy name into in buffer, at most sz bytes, if buffer is null will
3524 malloc buffer, call responsible for freeing */
3525 char* CyaSSL_X509_NAME_oneline(CYASSL_X509_NAME* name, char* in, int sz)
3527 int copySz = min(sz, name->sz);
3529 CYASSL_ENTER("CyaSSL_X509_NAME_oneline");
3530 if (!name->sz) return in;
3533 in = (char*)XMALLOC(name->sz, 0, DYNAMIC_TYPE_OPENSSL);
3534 if (!in ) return in;
3541 XMEMCPY(in, name->name, copySz - 1);
3548 CYASSL_X509* CyaSSL_X509_STORE_CTX_get_current_cert(
3549 CYASSL_X509_STORE_CTX* ctx)
3556 int CyaSSL_X509_STORE_CTX_get_error(CYASSL_X509_STORE_CTX* ctx)
3563 int CyaSSL_X509_STORE_CTX_get_error_depth(CYASSL_X509_STORE_CTX* ctx)
3570 CYASSL_BIO_METHOD* CyaSSL_BIO_f_buffer(void)
3572 static CYASSL_BIO_METHOD meth;
3574 CYASSL_ENTER("BIO_f_buffer");
3575 meth.type = BIO_BUFFER;
3581 long CyaSSL_BIO_set_write_buffer_size(CYASSL_BIO* bio, long size)
3583 /* CyaSSL has internal buffer, compatibility only */
3584 CYASSL_ENTER("BIO_set_write_buffer_size");
3590 CYASSL_BIO_METHOD* CyaSSL_BIO_f_ssl(void)
3592 static CYASSL_BIO_METHOD meth;
3594 CYASSL_ENTER("BIO_f_ssl");
3595 meth.type = BIO_SSL;
3601 CYASSL_BIO* CyaSSL_BIO_new_socket(int sfd, int closeF)
3603 CYASSL_BIO* bio = (CYASSL_BIO*) XMALLOC(sizeof(CYASSL_BIO), 0,
3604 DYNAMIC_TYPE_OPENSSL);
3606 CYASSL_ENTER("BIO_new_socket");
3608 bio->type = BIO_SOCKET;
3609 bio->close = (byte)closeF;
3620 int CyaSSL_BIO_eof(CYASSL_BIO* b)
3622 CYASSL_ENTER("BIO_eof");
3630 long CyaSSL_BIO_set_ssl(CYASSL_BIO* b, CYASSL* ssl, int closeF)
3632 CYASSL_ENTER("BIO_set_ssl");
3634 b->close = (byte)closeF;
3635 /* add to ssl for bio free if SSL_free called before/instead of free_all? */
3641 CYASSL_BIO* CyaSSL_BIO_new(CYASSL_BIO_METHOD* method)
3643 CYASSL_BIO* bio = (CYASSL_BIO*) XMALLOC(sizeof(CYASSL_BIO), 0,
3644 DYNAMIC_TYPE_OPENSSL);
3645 CYASSL_ENTER("BIO_new");
3647 bio->type = method->type;
3661 int CyaSSL_BIO_get_mem_data(CYASSL_BIO* bio, const byte** p)
3663 if (bio == NULL || p == NULL)
3672 CYASSL_BIO* CyaSSL_BIO_new_mem_buf(void* buf, int len)
3674 CYASSL_BIO* bio = NULL;
3678 bio = CyaSSL_BIO_new(CyaSSL_BIO_s_mem());
3683 bio->mem = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
3684 if (bio->mem == NULL) {
3685 XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
3689 XMEMCPY(bio->mem, buf, len);
3695 #ifdef USE_WINDOWS_API
3696 #define CloseSocket(s) closesocket(s)
3698 #define CloseSocket(s) close(s)
3701 int CyaSSL_BIO_free(CYASSL_BIO* bio)
3703 /* unchain?, doesn't matter in goahead since from free all */
3704 CYASSL_ENTER("BIO_free");
3708 CyaSSL_free(bio->ssl);
3710 CloseSocket(bio->fd);
3713 XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL);
3714 XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
3720 int CyaSSL_BIO_free_all(CYASSL_BIO* bio)
3722 CYASSL_ENTER("BIO_free_all");
3724 CYASSL_BIO* next = bio->next;
3725 CyaSSL_BIO_free(bio);
3732 int CyaSSL_BIO_read(CYASSL_BIO* bio, void* buf, int len)
3736 CYASSL_BIO* front = bio;
3738 CYASSL_ENTER("BIO_read");
3739 /* already got eof, again is error */
3741 return SSL_FATAL_ERROR;
3743 while(bio && ((ssl = bio->ssl) == 0) )
3746 if (ssl == 0) return BAD_FUNC_ARG;
3748 ret = CyaSSL_read(ssl, buf, len);
3752 int err = CyaSSL_get_error(ssl, 0);
3753 if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
3760 int CyaSSL_BIO_write(CYASSL_BIO* bio, const void* data, int len)
3764 CYASSL_BIO* front = bio;
3766 CYASSL_ENTER("BIO_write");
3767 /* already got eof, again is error */
3769 return SSL_FATAL_ERROR;
3771 while(bio && ((ssl = bio->ssl) == 0) )
3774 if (ssl == 0) return BAD_FUNC_ARG;
3776 ret = CyaSSL_write(ssl, data, len);
3780 int err = CyaSSL_get_error(ssl, 0);
3781 if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
3789 CYASSL_BIO* CyaSSL_BIO_push(CYASSL_BIO* top, CYASSL_BIO* append)
3791 CYASSL_ENTER("BIO_push");
3799 int CyaSSL_BIO_flush(CYASSL_BIO* bio)
3801 /* for CyaSSL no flushing needed */
3802 CYASSL_ENTER("BIO_flush");
3808 #endif /* OPENSSL_EXTRA || GOAHEAD_WS */
3811 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
3813 void CyaSSL_CTX_set_default_passwd_cb_userdata(CYASSL_CTX* ctx,
3816 CYASSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
3817 ctx->userdata = userdata;
3821 void CyaSSL_CTX_set_default_passwd_cb(CYASSL_CTX* ctx, pem_password_cb cb)
3823 CYASSL_ENTER("SSL_CTX_set_default_passwd_cb");
3824 ctx->passwd_cb = cb;
3827 int CyaSSL_num_locks(void)
3832 void CyaSSL_set_locking_callback(void (*f)(int, int, const char*, int))
3837 void CyaSSL_set_id_callback(unsigned long (*f)(void))
3842 unsigned long CyaSSL_ERR_get_error(void)
3848 int CyaSSL_EVP_BytesToKey(const CYASSL_EVP_CIPHER* type,
3849 const CYASSL_EVP_MD* md, const byte* salt,
3850 const byte* data, int sz, int count, byte* key, byte* iv)
3856 byte digest[MD5_DIGEST_SIZE];
3863 CYASSL_ENTER("EVP_BytesToKey");
3866 /* only support MD5 for now */
3867 if (XSTRNCMP(md, "MD5", 3)) return 0;
3869 /* only support CBC DES and AES for now */
3870 if (XSTRNCMP(type, "DES-CBC", 7) == 0) {
3871 keyLen = DES_KEY_SIZE;
3872 ivLen = DES_IV_SIZE;
3874 else if (XSTRNCMP(type, "DES-EDE3-CBC", 12) == 0) {
3875 keyLen = DES3_KEY_SIZE;
3876 ivLen = DES_IV_SIZE;
3878 else if (XSTRNCMP(type, "AES-128-CBC", 11) == 0) {
3879 keyLen = AES_128_KEY_SIZE;
3880 ivLen = AES_IV_SIZE;
3882 else if (XSTRNCMP(type, "AES-192-CBC", 11) == 0) {
3883 keyLen = AES_192_KEY_SIZE;
3884 ivLen = AES_IV_SIZE;
3886 else if (XSTRNCMP(type, "AES-256-CBC", 11) == 0) {
3887 keyLen = AES_256_KEY_SIZE;
3888 ivLen = AES_IV_SIZE;
3896 while (keyOutput < (keyLen + ivLen)) {
3897 int digestLeft = MD5_DIGEST_SIZE;
3899 if (keyOutput) /* first time D_0 is empty */
3900 Md5Update(&myMD, digest, MD5_DIGEST_SIZE);
3902 Md5Update(&myMD, data, sz);
3905 Md5Update(&myMD, salt, EVP_SALT_SIZE);
3906 Md5Final(&myMD, digest);
3908 for (j = 1; j < count; j++) {
3909 Md5Update(&myMD, digest, MD5_DIGEST_SIZE);
3910 Md5Final(&myMD, digest);
3914 int store = min(keyLeft, MD5_DIGEST_SIZE);
3915 XMEMCPY(&key[keyLen - keyLeft], digest, store);
3919 digestLeft -= store;
3922 if (ivLeft && digestLeft) {
3923 int store = min(ivLeft, digestLeft);
3924 XMEMCPY(&iv[ivLen - ivLeft], &digest[MD5_DIGEST_SIZE -
3925 digestLeft], store);
3930 if (keyOutput != (keyLen + ivLen))
3935 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
3938 #ifdef OPENSSL_EXTRA
3940 unsigned long CyaSSLeay(void)
3942 return SSLEAY_VERSION_NUMBER;
3946 const char* CyaSSLeay_version(int type)
3948 static const char* version = "SSLeay CyaSSL compatibility";
3954 void CyaSSL_MD5_Init(CYASSL_MD5_CTX* md5)
3956 typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
3957 (void)sizeof(md5_test);
3959 CYASSL_ENTER("MD5_Init");
3964 void CyaSSL_MD5_Update(CYASSL_MD5_CTX* md5, const void* input,
3967 CYASSL_ENTER("CyaSSL_MD5_Update");
3968 Md5Update((Md5*)md5, (const byte*)input, sz);
3972 void CyaSSL_MD5_Final(byte* input, CYASSL_MD5_CTX* md5)
3974 CYASSL_ENTER("MD5_Final");
3975 Md5Final((Md5*)md5, input);
3979 void CyaSSL_SHA_Init(CYASSL_SHA_CTX* sha)
3981 typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1];
3982 (void)sizeof(sha_test);
3984 CYASSL_ENTER("SHA_Init");
3989 void CyaSSL_SHA_Update(CYASSL_SHA_CTX* sha, const void* input,
3992 CYASSL_ENTER("SHA_Update");
3993 ShaUpdate((Sha*)sha, (const byte*)input, sz);
3997 void CyaSSL_SHA_Final(byte* input, CYASSL_SHA_CTX* sha)
3999 CYASSL_ENTER("SHA_Final");
4000 ShaFinal((Sha*)sha, input);
4004 void CyaSSL_SHA1_Init(CYASSL_SHA_CTX* sha)
4006 CYASSL_ENTER("SHA1_Init");
4011 void CyaSSL_SHA1_Update(CYASSL_SHA_CTX* sha, const void* input,
4014 CYASSL_ENTER("SHA1_Update");
4015 SHA_Update(sha, input, sz);
4019 void CyaSSL_SHA1_Final(byte* input, CYASSL_SHA_CTX* sha)
4021 CYASSL_ENTER("SHA1_Final");
4022 SHA_Final(input, sha);
4026 void CyaSSL_SHA256_Init(CYASSL_SHA256_CTX* sha256)
4028 typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
4029 (void)sizeof(sha_test);
4031 CYASSL_ENTER("SHA256_Init");
4032 InitSha256((Sha256*)sha256);
4036 void CyaSSL_SHA256_Update(CYASSL_SHA256_CTX* sha, const void* input,
4039 CYASSL_ENTER("SHA256_Update");
4040 Sha256Update((Sha256*)sha, (const byte*)input, sz);
4044 void CyaSSL_SHA256_Final(byte* input, CYASSL_SHA256_CTX* sha)
4046 CYASSL_ENTER("SHA256_Final");
4047 Sha256Final((Sha256*)sha, input);
4051 #ifdef CYASSL_SHA384
4053 void CyaSSL_SHA384_Init(CYASSL_SHA384_CTX* sha)
4055 typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
4056 (void)sizeof(sha_test);
4058 CYASSL_ENTER("SHA384_Init");
4059 InitSha384((Sha384*)sha);
4063 void CyaSSL_SHA384_Update(CYASSL_SHA384_CTX* sha, const void* input,
4066 CYASSL_ENTER("SHA384_Update");
4067 Sha384Update((Sha384*)sha, (const byte*)input, sz);
4071 void CyaSSL_SHA384_Final(byte* input, CYASSL_SHA384_CTX* sha)
4073 CYASSL_ENTER("SHA384_Final");
4074 Sha384Final((Sha384*)sha, input);
4077 #endif /* CYASSL_SHA384 */
4080 #ifdef CYASSL_SHA512
4082 void CyaSSL_SHA512_Init(CYASSL_SHA512_CTX* sha)
4084 typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
4085 (void)sizeof(sha_test);
4087 CYASSL_ENTER("SHA512_Init");
4088 InitSha512((Sha512*)sha);
4092 void CyaSSL_SHA512_Update(CYASSL_SHA512_CTX* sha, const void* input,
4095 CYASSL_ENTER("SHA512_Update");
4096 Sha512Update((Sha512*)sha, (const byte*)input, sz);
4100 void CyaSSL_SHA512_Final(byte* input, CYASSL_SHA512_CTX* sha)
4102 CYASSL_ENTER("SHA512_Final");
4103 Sha512Final((Sha512*)sha, input);
4106 #endif /* CYASSL_SHA512 */
4109 const CYASSL_EVP_MD* CyaSSL_EVP_md5(void)
4111 static const char* type = "MD5";
4112 CYASSL_ENTER("EVP_md5");
4117 const CYASSL_EVP_MD* CyaSSL_EVP_sha1(void)
4119 static const char* type = "SHA";
4120 CYASSL_ENTER("EVP_sha1");
4125 const CYASSL_EVP_MD* CyaSSL_EVP_sha256(void)
4127 static const char* type = "SHA256";
4128 CYASSL_ENTER("EVP_sha256");
4132 #ifdef CYASSL_SHA384
4134 const CYASSL_EVP_MD* CyaSSL_EVP_sha384(void)
4136 static const char* type = "SHA384";
4137 CYASSL_ENTER("EVP_sha384");
4141 #endif /* CYASSL_SHA384 */
4143 #ifdef CYASSL_SHA512
4145 const CYASSL_EVP_MD* CyaSSL_EVP_sha512(void)
4147 static const char* type = "SHA512";
4148 CYASSL_ENTER("EVP_sha512");
4152 #endif /* CYASSL_SHA512 */
4155 void CyaSSL_EVP_MD_CTX_init(CYASSL_EVP_MD_CTX* ctx)
4157 CYASSL_ENTER("EVP_CIPHER_MD_CTX_init");
4163 const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_128_cbc(void)
4165 static const char* type = "AES128-CBC";
4166 CYASSL_ENTER("CyaSSL_EVP_aes_128_cbc");
4171 const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_192_cbc(void)
4173 static const char* type = "AES192-CBC";
4174 CYASSL_ENTER("CyaSSL_EVP_aes_192_cbc");
4179 const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_256_cbc(void)
4181 static const char* type = "AES256-CBC";
4182 CYASSL_ENTER("CyaSSL_EVP_aes_256_cbc");
4187 const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_128_ctr(void)
4189 static const char* type = "AES128-CTR";
4190 CYASSL_ENTER("CyaSSL_EVP_aes_128_ctr");
4195 const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_192_ctr(void)
4197 static const char* type = "AES192-CTR";
4198 CYASSL_ENTER("CyaSSL_EVP_aes_192_ctr");
4203 const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_256_ctr(void)
4205 static const char* type = "AES256-CTR";
4206 CYASSL_ENTER("CyaSSL_EVP_aes_256_ctr");
4211 const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_cbc(void)
4213 static const char* type = "DES-CBC";
4214 CYASSL_ENTER("CyaSSL_EVP_des_cbc");
4219 const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_ede3_cbc(void)
4221 static const char* type = "DES-EDE3-CBC";
4222 CYASSL_ENTER("CyaSSL_EVP_des_ede3_cbc");
4227 const CYASSL_EVP_CIPHER* CyaSSL_EVP_rc4(void)
4229 static const char* type = "ARC4";
4230 CYASSL_ENTER("CyaSSL_EVP_rc4");
4235 const CYASSL_EVP_CIPHER* CyaSSL_EVP_enc_null(void)
4237 static const char* type = "NULL";
4238 CYASSL_ENTER("CyaSSL_EVP_enc_null");
4243 int CyaSSL_EVP_MD_CTX_cleanup(CYASSL_EVP_MD_CTX* ctx)
4245 CYASSL_ENTER("EVP_MD_CTX_cleanup");
4252 void CyaSSL_EVP_CIPHER_CTX_init(CYASSL_EVP_CIPHER_CTX* ctx)
4254 CYASSL_ENTER("EVP_CIPHER_CTX_init");
4256 ctx->cipherType = 0xff; /* no init */
4258 ctx->enc = 1; /* start in encrypt mode */
4263 int CyaSSL_EVP_CIPHER_CTX_cleanup(CYASSL_EVP_CIPHER_CTX* ctx)
4265 CYASSL_ENTER("EVP_CIPHER_CTX_cleanup");
4267 ctx->cipherType = 0xff; /* no more init */
4271 return 1; /* success */
4274 int CyaSSL_EVP_CipherInit(CYASSL_EVP_CIPHER_CTX* ctx,
4275 const CYASSL_EVP_CIPHER* type, byte* key,
4278 CYASSL_ENTER("CyaSSL_EVP_CipherInit");
4280 CYASSL_MSG("no ctx");
4281 return 0; /* failure */
4284 if (type == NULL && ctx->cipherType == 0xff) {
4285 CYASSL_MSG("no type set");
4286 return 0; /* failure */
4289 if (ctx->cipherType == AES_128_CBC_TYPE || (type &&
4290 XSTRNCMP(type, "AES128-CBC", 10) == 0)) {
4291 CYASSL_MSG("AES-128-CBC");
4292 ctx->cipherType = AES_128_CBC_TYPE;
4294 if (enc == 0 || enc == 1)
4295 ctx->enc = enc ? 1 : 0;
4297 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4298 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
4299 if (iv && key == NULL)
4300 AesSetIV(&ctx->cipher.aes, iv);
4302 else if (ctx->cipherType == AES_192_CBC_TYPE || (type &&
4303 XSTRNCMP(type, "AES192-CBC", 10) == 0)) {
4304 CYASSL_MSG("AES-192-CBC");
4305 ctx->cipherType = AES_192_CBC_TYPE;
4307 if (enc == 0 || enc == 1)
4308 ctx->enc = enc ? 1 : 0;
4310 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4311 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
4312 if (iv && key == NULL)
4313 AesSetIV(&ctx->cipher.aes, iv);
4315 else if (ctx->cipherType == AES_256_CBC_TYPE || (type &&
4316 XSTRNCMP(type, "AES256-CBC", 10) == 0)) {
4317 CYASSL_MSG("AES-256-CBC");
4318 ctx->cipherType = AES_256_CBC_TYPE;
4320 if (enc == 0 || enc == 1)
4321 ctx->enc = enc ? 1 : 0;
4323 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4324 ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
4325 if (iv && key == NULL)
4326 AesSetIV(&ctx->cipher.aes, iv);
4328 #ifdef CYASSL_AES_COUNTER
4329 else if (ctx->cipherType == AES_128_CTR_TYPE || (type &&
4330 XSTRNCMP(type, "AES128-CTR", 10) == 0)) {
4331 CYASSL_MSG("AES-128-CTR");
4332 ctx->cipherType = AES_128_CTR_TYPE;
4334 if (enc == 0 || enc == 1)
4335 ctx->enc = enc ? 1 : 0;
4337 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4339 if (iv && key == NULL)
4340 AesSetIV(&ctx->cipher.aes, iv);
4342 else if (ctx->cipherType == AES_192_CTR_TYPE || (type &&
4343 XSTRNCMP(type, "AES192-CTR", 10) == 0)) {
4344 CYASSL_MSG("AES-192-CTR");
4345 ctx->cipherType = AES_192_CTR_TYPE;
4347 if (enc == 0 || enc == 1)
4348 ctx->enc = enc ? 1 : 0;
4350 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4352 if (iv && key == NULL)
4353 AesSetIV(&ctx->cipher.aes, iv);
4355 else if (ctx->cipherType == AES_256_CTR_TYPE || (type &&
4356 XSTRNCMP(type, "AES256-CTR", 10) == 0)) {
4357 CYASSL_MSG("AES-256-CTR");
4358 ctx->cipherType = AES_256_CTR_TYPE;
4360 if (enc == 0 || enc == 1)
4361 ctx->enc = enc ? 1 : 0;
4363 AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
4365 if (iv && key == NULL)
4366 AesSetIV(&ctx->cipher.aes, iv);
4368 #endif /* CYASSL_AES_CTR */
4369 else if (ctx->cipherType == DES_CBC_TYPE || (type &&
4370 XSTRNCMP(type, "DES-CBC", 7) == 0)) {
4371 CYASSL_MSG("DES-CBC");
4372 ctx->cipherType = DES_CBC_TYPE;
4374 if (enc == 0 || enc == 1)
4375 ctx->enc = enc ? 1 : 0;
4377 Des_SetKey(&ctx->cipher.des, key, iv,
4378 ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
4379 if (iv && key == NULL)
4380 Des_SetIV(&ctx->cipher.des, iv);
4382 else if (ctx->cipherType == DES_EDE3_CBC_TYPE || (type &&
4383 XSTRNCMP(type, "DES-EDE3-CBC", 11) == 0)) {
4384 CYASSL_MSG("DES-EDE3-CBC");
4385 ctx->cipherType = DES_EDE3_CBC_TYPE;
4387 if (enc == 0 || enc == 1)
4388 ctx->enc = enc ? 1 : 0;
4390 Des3_SetKey(&ctx->cipher.des3, key, iv,
4391 ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
4392 if (iv && key == NULL)
4393 Des3_SetIV(&ctx->cipher.des3, iv);
4395 else if (ctx->cipherType == ARC4_TYPE || (type &&
4396 XSTRNCMP(type, "ARC4", 4) == 0)) {
4398 ctx->cipherType = ARC4_TYPE;
4399 if (ctx->keyLen == 0) /* user may have already set */
4400 ctx->keyLen = 16; /* default to 128 */
4402 Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
4404 else if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
4405 XSTRNCMP(type, "NULL", 4) == 0)) {
4406 CYASSL_MSG("NULL cipher");
4407 ctx->cipherType = NULL_CIPHER_TYPE;
4411 return 0; /* failure */
4414 return 1; /* success */
4418 int CyaSSL_EVP_CIPHER_CTX_key_length(CYASSL_EVP_CIPHER_CTX* ctx)
4420 CYASSL_ENTER("CyaSSL_EVP_CIPHER_CTX_key_length");
4424 return 0; /* failure */
4428 int CyaSSL_EVP_CIPHER_CTX_set_key_length(CYASSL_EVP_CIPHER_CTX* ctx,
4431 CYASSL_ENTER("CyaSSL_EVP_CIPHER_CTX_set_key_length");
4433 ctx->keyLen = keylen;
4435 return 0; /* failure */
4437 return 1; /* success */
4441 int CyaSSL_EVP_Cipher(CYASSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
4444 CYASSL_ENTER("CyaSSL_EVP_Cipher");
4446 if (ctx == NULL || dst == NULL || src == NULL) {
4447 CYASSL_MSG("Bad function argument");
4448 return 0; /* failure */
4451 if (ctx->cipherType == 0xff) {
4452 CYASSL_MSG("no init");
4453 return 0; /* failure */
4456 switch (ctx->cipherType) {
4458 case AES_128_CBC_TYPE :
4459 case AES_192_CBC_TYPE :
4460 case AES_256_CBC_TYPE :
4461 CYASSL_MSG("AES CBC");
4463 AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
4465 AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
4468 #ifdef CYASSL_AES_COUNTER
4469 case AES_128_CTR_TYPE :
4470 case AES_192_CTR_TYPE :
4471 case AES_256_CTR_TYPE :
4472 CYASSL_MSG("AES CTR");
4473 AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
4479 Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
4481 Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
4484 case DES_EDE3_CBC_TYPE :
4486 Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
4488 Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
4492 Arc4Process(&ctx->cipher.arc4, dst, src, len);
4495 case NULL_CIPHER_TYPE :
4496 XMEMCPY(dst, src, len);
4500 CYASSL_MSG("bad type");
4501 return 0; /* failure */
4505 CYASSL_MSG("CyaSSL_EVP_Cipher success");
4506 return 1; /* success */
4510 /* store for external read of iv, 0 on success */
4511 int CyaSSL_StoreExternalIV(CYASSL_EVP_CIPHER_CTX* ctx)
4513 CYASSL_ENTER("CyaSSL_StoreExternalIV");
4516 CYASSL_MSG("Bad function argument");
4520 switch (ctx->cipherType) {
4522 case AES_128_CBC_TYPE :
4523 case AES_192_CBC_TYPE :
4524 case AES_256_CBC_TYPE :
4525 CYASSL_MSG("AES CBC");
4526 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
4529 #ifdef CYASSL_AES_COUNTER
4530 case AES_128_CTR_TYPE :
4531 case AES_192_CTR_TYPE :
4532 case AES_256_CTR_TYPE :
4533 CYASSL_MSG("AES CTR");
4534 memcpy(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
4539 CYASSL_MSG("DES CBC");
4540 memcpy(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
4543 case DES_EDE3_CBC_TYPE :
4544 CYASSL_MSG("DES EDE3 CBC");
4545 memcpy(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
4552 case NULL_CIPHER_TYPE :
4557 CYASSL_MSG("bad type");
4558 return -1; /* failure */
4561 return 0; /* success */
4565 /* set internal IV from external, 0 on success */
4566 int CyaSSL_SetInternalIV(CYASSL_EVP_CIPHER_CTX* ctx)
4569 CYASSL_ENTER("CyaSSL_SetInternalIV");
4572 CYASSL_MSG("Bad function argument");
4576 switch (ctx->cipherType) {
4578 case AES_128_CBC_TYPE :
4579 case AES_192_CBC_TYPE :
4580 case AES_256_CBC_TYPE :
4581 CYASSL_MSG("AES CBC");
4582 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
4585 #ifdef CYASSL_AES_COUNTER
4586 case AES_128_CTR_TYPE :
4587 case AES_192_CTR_TYPE :
4588 case AES_256_CTR_TYPE :
4589 CYASSL_MSG("AES CTR");
4590 memcpy(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
4595 CYASSL_MSG("DES CBC");
4596 memcpy(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
4599 case DES_EDE3_CBC_TYPE :
4600 CYASSL_MSG("DES EDE3 CBC");
4601 memcpy(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
4608 case NULL_CIPHER_TYPE :
4613 CYASSL_MSG("bad type");
4614 return -1; /* failure */
4617 return 0; /* success */
4621 int CyaSSL_EVP_DigestInit(CYASSL_EVP_MD_CTX* ctx, const CYASSL_EVP_MD* type)
4623 CYASSL_ENTER("EVP_DigestInit");
4624 if (XSTRNCMP(type, "MD5", 3) == 0) {
4626 CyaSSL_MD5_Init((MD5_CTX*)&ctx->hash);
4628 else if (XSTRNCMP(type, "SHA256", 6) == 0) {
4629 ctx->macType = SHA256;
4630 CyaSSL_SHA256_Init((SHA256_CTX*)&ctx->hash);
4632 #ifdef CYASSL_SHA384
4633 else if (XSTRNCMP(type, "SHA384", 6) == 0) {
4634 ctx->macType = SHA384;
4635 CyaSSL_SHA384_Init((SHA384_CTX*)&ctx->hash);
4638 #ifdef CYASSL_SHA512
4639 else if (XSTRNCMP(type, "SHA512", 6) == 0) {
4640 ctx->macType = SHA512;
4641 CyaSSL_SHA512_Init((SHA512_CTX*)&ctx->hash);
4644 /* has to be last since would pick or 256, 384, or 512 too */
4645 else if (XSTRNCMP(type, "SHA", 3) == 0) {
4647 CyaSSL_SHA_Init((SHA_CTX*)&ctx->hash);
4650 return BAD_FUNC_ARG;
4656 int CyaSSL_EVP_DigestUpdate(CYASSL_EVP_MD_CTX* ctx, const void* data,
4659 CYASSL_ENTER("EVP_DigestUpdate");
4660 if (ctx->macType == MD5)
4661 CyaSSL_MD5_Update((MD5_CTX*)&ctx->hash, data, (unsigned long)sz);
4662 else if (ctx->macType == SHA)
4663 CyaSSL_SHA_Update((SHA_CTX*)&ctx->hash, data, (unsigned long)sz);
4664 else if (ctx->macType == SHA256)
4665 CyaSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
4667 #ifdef CYASSL_SHA384
4668 else if (ctx->macType == SHA384)
4669 CyaSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
4672 #ifdef CYASSL_SHA512
4673 else if (ctx->macType == SHA512)
4674 CyaSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
4678 return BAD_FUNC_ARG;
4684 int CyaSSL_EVP_DigestFinal(CYASSL_EVP_MD_CTX* ctx, unsigned char* md,
4687 CYASSL_ENTER("EVP_DigestFinal");
4688 if (ctx->macType == MD5) {
4689 CyaSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
4690 if (s) *s = MD5_DIGEST_SIZE;
4692 else if (ctx->macType == SHA) {
4693 CyaSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
4694 if (s) *s = SHA_DIGEST_SIZE;
4696 else if (ctx->macType == SHA256) {
4697 CyaSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
4698 if (s) *s = SHA256_DIGEST_SIZE;
4700 #ifdef CYASSL_SHA384
4701 else if (ctx->macType == SHA384) {
4702 CyaSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
4703 if (s) *s = SHA384_DIGEST_SIZE;
4706 #ifdef CYASSL_SHA512
4707 else if (ctx->macType == SHA512) {
4708 CyaSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
4709 if (s) *s = SHA512_DIGEST_SIZE;
4713 return BAD_FUNC_ARG;
4719 int CyaSSL_EVP_DigestFinal_ex(CYASSL_EVP_MD_CTX* ctx, unsigned char* md,
4722 CYASSL_ENTER("EVP_DigestFinal_ex");
4723 return EVP_DigestFinal(ctx, md, s);
4727 unsigned char* CyaSSL_HMAC(const CYASSL_EVP_MD* evp_md, const void* key,
4728 int key_len, const unsigned char* d, int n,
4729 unsigned char* md, unsigned int* md_len)
4733 CYASSL_ENTER("HMAC");
4734 if (!md) return 0; /* no static buffer support */
4736 if (XSTRNCMP(evp_md, "MD5", 3) == 0) {
4737 HmacSetKey(&hmac, MD5, (const byte*)key, key_len);
4738 if (md_len) *md_len = MD5_DIGEST_SIZE;
4740 else if (XSTRNCMP(evp_md, "SHA", 3) == 0) {
4741 HmacSetKey(&hmac, SHA, (const byte*)key, key_len);
4742 if (md_len) *md_len = SHA_DIGEST_SIZE;
4747 HmacUpdate(&hmac, d, n);
4748 HmacFinal(&hmac, md);
4753 void CyaSSL_ERR_clear_error(void)
4759 int CyaSSL_RAND_status(void)
4761 return 1; /* CTaoCrypt provides enough seed internally */
4766 void CyaSSL_RAND_add(const void* add, int len, double entropy)
4772 /* CyaSSL seeds/adds internally, use explicit RNG if you want
4777 int CyaSSL_DES_key_sched(CYASSL_const_DES_cblock* key,
4778 CYASSL_DES_key_schedule* schedule)
4780 CYASSL_ENTER("DES_key_sched");
4781 XMEMCPY(schedule, key, sizeof(const_DES_cblock));
4786 void CyaSSL_DES_cbc_encrypt(const unsigned char* input,
4787 unsigned char* output, long length,
4788 CYASSL_DES_key_schedule* schedule, CYASSL_DES_cblock* ivec,
4792 CYASSL_ENTER("DES_cbc_encrypt");
4793 Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
4796 Des_CbcEncrypt(&myDes, output, input, length);
4798 Des_CbcDecrypt(&myDes, output, input, length);
4802 /* correctly sets ivec for next call */
4803 void CyaSSL_DES_ncbc_encrypt(const unsigned char* input,
4804 unsigned char* output, long length,
4805 CYASSL_DES_key_schedule* schedule, CYASSL_DES_cblock* ivec,
4809 CYASSL_ENTER("DES_ncbc_encrypt");
4810 Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
4813 Des_CbcEncrypt(&myDes, output, input, length);
4815 Des_CbcDecrypt(&myDes, output, input, length);
4817 XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
4821 void CyaSSL_ERR_free_strings(void)
4823 /* handled internally */
4827 void CyaSSL_ERR_remove_state(unsigned long state)
4829 /* TODO: GetErrors().Remove(); */
4834 void CyaSSL_EVP_cleanup(void)
4836 /* nothing to do here */
4840 void CyaSSL_cleanup_all_ex_data(void)
4842 /* nothing to do here */
4846 long CyaSSL_CTX_set_mode(CYASSL_CTX* ctx, long mode)
4848 /* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is CyaSSL default mode */
4850 CYASSL_ENTER("SSL_CTX_set_mode");
4851 if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
4852 ctx->partialWrite = 1;
4858 long CyaSSL_CTX_get_mode(CYASSL_CTX* ctx)
4866 void CyaSSL_CTX_set_default_read_ahead(CYASSL_CTX* ctx, int m)
4874 int CyaSSL_CTX_set_session_id_context(CYASSL_CTX* ctx,
4875 const unsigned char* sid_ctx,
4876 unsigned int sid_ctx_len)
4878 /* No application specific context needed for cyaSSL */
4886 long CyaSSL_CTX_sess_get_cache_size(CYASSL_CTX* ctx)
4893 unsigned long CyaSSL_ERR_get_error_line_data(const char** file, int* line,
4894 const char** data, int *flags)
4896 /* Not implemented */
4905 CYASSL_X509* CyaSSL_get_peer_certificate(CYASSL* ssl)
4907 CYASSL_ENTER("SSL_get_peer_certificate");
4908 if (ssl->peerCert.issuer.sz)
4909 return &ssl->peerCert;
4916 int CyaSSL_set_ex_data(CYASSL* ssl, int idx, void* data)
4919 if (ssl != NULL && idx < MAX_EX_DATA)
4921 ssl->ex_data[idx] = data;
4933 int CyaSSL_get_shutdown(const CYASSL* ssl)
4940 int CyaSSL_set_session_id_context(CYASSL* ssl, const unsigned char* id,
4950 void CyaSSL_set_connect_state(CYASSL* ssl)
4953 /* client by default */
4957 int CyaSSL_session_reused(CYASSL* ssl)
4959 return ssl->options.resuming;
4963 void CyaSSL_SESSION_free(CYASSL_SESSION* session)
4969 const char* CyaSSL_get_version(CYASSL* ssl)
4971 CYASSL_ENTER("SSL_get_version");
4972 if (ssl->version.major == SSLv3_MAJOR) {
4973 switch (ssl->version.minor) {
4978 case TLSv1_1_MINOR :
4980 case TLSv1_2_MINOR :
4986 else if (ssl->version.major == DTLS_MAJOR)
4992 CYASSL_CIPHER* CyaSSL_get_current_cipher(CYASSL* ssl)
4994 CYASSL_ENTER("SSL_get_current_cipher");
4996 return &ssl->cipher;
5002 const char* CyaSSL_CIPHER_get_name(const CYASSL_CIPHER* cipher)
5004 CYASSL_ENTER("SSL_CIPHER_get_name");
5007 if (cipher->ssl->options.cipherSuite0 == ECC_BYTE) {
5009 switch (cipher->ssl->options.cipherSuite) {
5010 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
5011 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
5012 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
5013 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
5014 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
5015 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
5016 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
5017 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
5018 case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
5019 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
5020 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
5021 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
5022 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
5023 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
5024 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
5025 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
5027 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
5028 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
5029 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
5030 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
5031 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
5032 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
5033 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
5034 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
5035 case TLS_ECDH_RSA_WITH_RC4_128_SHA :
5036 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
5037 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
5038 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
5039 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
5040 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
5041 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
5042 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
5044 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
5045 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
5046 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
5047 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
5048 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
5049 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
5050 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
5051 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
5052 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
5053 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
5054 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
5055 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
5056 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
5057 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
5058 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
5059 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
5066 if (cipher->ssl->options.cipherSuite0 != ECC_BYTE) {
5068 switch (cipher->ssl->options.cipherSuite) {
5069 case SSL_RSA_WITH_RC4_128_SHA :
5070 return "SSL_RSA_WITH_RC4_128_SHA";
5071 case SSL_RSA_WITH_RC4_128_MD5 :
5072 return "SSL_RSA_WITH_RC4_128_MD5";
5073 case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
5074 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
5075 case TLS_RSA_WITH_AES_128_CBC_SHA :
5076 return "TLS_RSA_WITH_AES_128_CBC_SHA";
5077 case TLS_RSA_WITH_AES_256_CBC_SHA :
5078 return "TLS_RSA_WITH_AES_256_CBC_SHA";
5079 case TLS_RSA_WITH_AES_128_CBC_SHA256 :
5080 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
5081 case TLS_RSA_WITH_AES_256_CBC_SHA256 :
5082 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
5083 case TLS_PSK_WITH_AES_128_CBC_SHA :
5084 return "TLS_PSK_WITH_AES_128_CBC_SHA";
5085 case TLS_PSK_WITH_AES_256_CBC_SHA :
5086 return "TLS_PSK_WITH_AES_256_CBC_SHA";
5087 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
5088 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
5089 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
5090 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
5091 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
5092 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
5093 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
5094 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
5095 case TLS_RSA_WITH_HC_128_CBC_MD5 :
5096 return "TLS_RSA_WITH_HC_128_CBC_MD5";
5097 case TLS_RSA_WITH_HC_128_CBC_SHA :
5098 return "TLS_RSA_WITH_HC_128_CBC_SHA";
5099 case TLS_RSA_WITH_RABBIT_CBC_SHA :
5100 return "TLS_RSA_WITH_RABBIT_CBC_SHA";
5101 case TLS_NTRU_RSA_WITH_RC4_128_SHA :
5102 return "TLS_NTRU_RSA_WITH_RC4_128_SHA";
5103 case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
5104 return "TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA";
5105 case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
5106 return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
5107 case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
5108 return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
5109 case TLS_RSA_WITH_AES_128_GCM_SHA256 :
5110 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
5111 case TLS_RSA_WITH_AES_256_GCM_SHA384 :
5112 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
5113 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
5114 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
5115 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
5116 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
5120 } /* normal / ECC */
5127 const char* CyaSSL_get_cipher(CYASSL* ssl)
5129 CYASSL_ENTER("CyaSSL_get_cipher");
5130 return CyaSSL_CIPHER_get_name(CyaSSL_get_current_cipher(ssl));
5134 /* server ctx Diffie-Hellman parameters */
5135 int CyaSSL_CTX_SetTmpDH(CYASSL_CTX* ctx, const unsigned char* p, int pSz,
5136 const unsigned char* g, int gSz)
5138 CYASSL_ENTER("CyaSSL_CTX_SetTmpDH");
5139 if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
5141 XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
5142 XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
5144 ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH);
5145 if (ctx->serverDH_P.buffer == NULL)
5148 ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH);
5149 if (ctx->serverDH_G.buffer == NULL) {
5150 XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
5154 ctx->serverDH_P.length = pSz;
5155 ctx->serverDH_G.length = gSz;
5157 XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
5158 XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
5162 CYASSL_LEAVE("CyaSSL_CTX_SetTmpDH", 0);
5167 char* CyaSSL_CIPHER_description(CYASSL_CIPHER* cipher, char* in, int len)
5176 CYASSL_SESSION* CyaSSL_get1_session(CYASSL* ssl) /* what's ref count */
5183 void CyaSSL_X509_free(CYASSL_X509* buf)
5189 /* was do nothing */
5191 void OPENSSL_free(void* buf)
5198 int CyaSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
5210 CYASSL_METHOD* CyaSSLv2_client_method(void)
5216 CYASSL_METHOD* CyaSSLv2_server_method(void)
5224 void CyaSSL_MD4_Init(CYASSL_MD4_CTX* md4)
5226 /* make sure we have a big enough buffer */
5227 typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
5230 CYASSL_ENTER("MD4_Init");
5235 void CyaSSL_MD4_Update(CYASSL_MD4_CTX* md4, const void* data,
5238 CYASSL_ENTER("MD4_Update");
5239 Md4Update((Md4*)md4, (const byte*)data, (word32)len);
5243 void CyaSSL_MD4_Final(unsigned char* digest, CYASSL_MD4_CTX* md4)
5245 CYASSL_ENTER("MD4_Final");
5246 Md4Final((Md4*)md4, digest);
5252 CYASSL_BIO* CyaSSL_BIO_pop(CYASSL_BIO* top)
5259 int CyaSSL_BIO_pending(CYASSL_BIO* bio)
5267 CYASSL_BIO_METHOD* CyaSSL_BIO_s_mem(void)
5269 static CYASSL_BIO_METHOD meth;
5271 CYASSL_ENTER("BIO_s_mem");
5272 meth.type = BIO_MEMORY;
5278 CYASSL_BIO_METHOD* CyaSSL_BIO_f_base64(void)
5284 void CyaSSL_BIO_set_flags(CYASSL_BIO* bio, int flags)
5292 void CyaSSL_RAND_screen(void)
5298 const char* CyaSSL_RAND_file_name(char* fname, unsigned long len)
5306 int CyaSSL_RAND_write_file(const char* fname)
5313 int CyaSSL_RAND_load_file(const char* fname, long len)
5316 /* CTaoCrypt provides enough entropy internally or will report error */
5324 int CyaSSL_RAND_egd(const char* path)
5332 CYASSL_COMP_METHOD* CyaSSL_COMP_zlib(void)
5338 CYASSL_COMP_METHOD* CyaSSL_COMP_rle(void)
5344 int CyaSSL_COMP_add_compression_method(int method, void* data)
5353 int CyaSSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
5365 void CyaSSL_set_dynlock_create_callback(CYASSL_dynlock_value* (*f)(
5372 void CyaSSL_set_dynlock_lock_callback(
5373 void (*f)(int, CYASSL_dynlock_value*, const char*, int))
5379 void CyaSSL_set_dynlock_destroy_callback(
5380 void (*f)(CYASSL_dynlock_value*, const char*, int))
5387 const char* CyaSSL_X509_verify_cert_error_string(long err)
5395 int CyaSSL_X509_LOOKUP_add_dir(CYASSL_X509_LOOKUP* lookup, const char* dir,
5405 int CyaSSL_X509_LOOKUP_load_file(CYASSL_X509_LOOKUP* lookup,
5406 const char* file, long len)
5415 CYASSL_X509_LOOKUP_METHOD* CyaSSL_X509_LOOKUP_hash_dir(void)
5421 CYASSL_X509_LOOKUP_METHOD* CyaSSL_X509_LOOKUP_file(void)
5428 CYASSL_X509_LOOKUP* CyaSSL_X509_STORE_add_lookup(CYASSL_X509_STORE* store,
5429 CYASSL_X509_LOOKUP_METHOD* m)
5437 CYASSL_X509_STORE* CyaSSL_X509_STORE_new(void)
5443 int CyaSSL_X509_STORE_get_by_subject(CYASSL_X509_STORE_CTX* ctx, int idx,
5444 CYASSL_X509_NAME* name, CYASSL_X509_OBJECT* obj)
5454 int CyaSSL_X509_STORE_CTX_init(CYASSL_X509_STORE_CTX* ctx,
5455 CYASSL_X509_STORE* store, CYASSL_X509* x509, STACK_OF(CYASSL_X509)* sk)
5465 void CyaSSL_X509_STORE_CTX_cleanup(CYASSL_X509_STORE_CTX* ctx)
5472 CYASSL_ASN1_TIME* CyaSSL_X509_CRL_get_lastUpdate(CYASSL_X509_CRL* crl)
5479 CYASSL_ASN1_TIME* CyaSSL_X509_CRL_get_nextUpdate(CYASSL_X509_CRL* crl)
5487 CYASSL_EVP_PKEY* CyaSSL_X509_get_pubkey(CYASSL_X509* x509)
5494 int CyaSSL_X509_CRL_verify(CYASSL_X509_CRL* crl, CYASSL_EVP_PKEY* key)
5502 void CyaSSL_X509_STORE_CTX_set_error(CYASSL_X509_STORE_CTX* ctx, int err)
5509 void CyaSSL_X509_OBJECT_free_contents(CYASSL_X509_OBJECT* obj)
5515 void CyaSSL_EVP_PKEY_free(CYASSL_EVP_PKEY* key)
5521 int CyaSSL_X509_cmp_current_time(const CYASSL_ASN1_TIME* asnTime)
5528 int CyaSSL_sk_X509_REVOKED_num(CYASSL_X509_REVOKED* revoked)
5536 CYASSL_X509_REVOKED* CyaSSL_X509_CRL_get_REVOKED(CYASSL_X509_CRL* crl)
5543 CYASSL_X509_REVOKED* CyaSSL_sk_X509_REVOKED_value(
5544 CYASSL_X509_REVOKED* revoked, int value)
5553 CYASSL_ASN1_INTEGER* CyaSSL_X509_get_serialNumber(CYASSL_X509* x509)
5560 int CyaSSL_ASN1_TIME_print(CYASSL_BIO* bio, const CYASSL_ASN1_TIME* asnTime)
5569 int CyaSSL_ASN1_INTEGER_cmp(const CYASSL_ASN1_INTEGER* a,
5570 const CYASSL_ASN1_INTEGER* b)
5578 long CyaSSL_ASN1_INTEGER_get(const CYASSL_ASN1_INTEGER* i)
5586 void* CyaSSL_X509_STORE_CTX_get_ex_data(CYASSL_X509_STORE_CTX* ctx, int idx)
5589 if (ctx != NULL && idx == 0)
5590 return ctx->ex_data;
5599 int CyaSSL_get_ex_data_X509_STORE_CTX_idx(void)
5605 void* CyaSSL_get_ex_data(const CYASSL* ssl, int idx)
5608 if (ssl != NULL && idx < MAX_EX_DATA)
5609 return ssl->ex_data[idx];
5618 void CyaSSL_CTX_set_info_callback(CYASSL_CTX* ctx, void (*f)(void))
5625 unsigned long CyaSSL_ERR_peek_error(void)
5631 int CyaSSL_ERR_GET_REASON(int err)
5638 char* CyaSSL_alert_type_string_long(int alertID)
5645 char* CyaSSL_alert_desc_string_long(int alertID)
5652 char* CyaSSL_state_string_long(CYASSL* ssl)
5659 int CyaSSL_PEM_def_callback(char* name, int num, int w, void* key)
5669 long CyaSSL_CTX_sess_accept(CYASSL_CTX* ctx)
5676 long CyaSSL_CTX_sess_connect(CYASSL_CTX* ctx)
5683 long CyaSSL_CTX_sess_accept_good(CYASSL_CTX* ctx)
5690 long CyaSSL_CTX_sess_connect_good(CYASSL_CTX* ctx)
5697 long CyaSSL_CTX_sess_accept_renegotiate(CYASSL_CTX* ctx)
5704 long CyaSSL_CTX_sess_connect_renegotiate(CYASSL_CTX* ctx)
5711 long CyaSSL_CTX_sess_hits(CYASSL_CTX* ctx)
5718 long CyaSSL_CTX_sess_cb_hits(CYASSL_CTX* ctx)
5725 long CyaSSL_CTX_sess_cache_full(CYASSL_CTX* ctx)
5732 long CyaSSL_CTX_sess_misses(CYASSL_CTX* ctx)
5739 long CyaSSL_CTX_sess_timeouts(CYASSL_CTX* ctx)
5746 long CyaSSL_CTX_sess_number(CYASSL_CTX* ctx)
5753 void CyaSSL_DES_set_key_unchecked(CYASSL_const_DES_cblock* myDes,
5754 CYASSL_DES_key_schedule* key)
5761 void CyaSSL_DES_set_odd_parity(CYASSL_DES_cblock* myDes)
5767 void CyaSSL_DES_ecb_encrypt(CYASSL_DES_cblock* desa,
5768 CYASSL_DES_cblock* desb, CYASSL_DES_key_schedule* key, int len)
5776 int CyaSSL_BIO_printf(CYASSL_BIO* bio, const char* format, ...)
5784 int CyaSSL_ASN1_UTCTIME_print(CYASSL_BIO* bio, const CYASSL_ASN1_UTCTIME* a)
5792 int CyaSSL_sk_num(CYASSL_X509_REVOKED* rev)
5799 void* CyaSSL_sk_value(CYASSL_X509_REVOKED* rev, int i)
5807 /* stunnel 4.28 needs */
5808 void* CyaSSL_CTX_get_ex_data(const CYASSL_CTX* ctx, int d)
5816 int CyaSSL_CTX_set_ex_data(CYASSL_CTX* ctx, int d, void* p)
5825 void CyaSSL_CTX_sess_set_get_cb(CYASSL_CTX* ctx,
5826 CYASSL_SESSION*(*f)(CYASSL*, unsigned char*, int, int*))
5833 void CyaSSL_CTX_sess_set_new_cb(CYASSL_CTX* ctx,
5834 int (*f)(CYASSL*, CYASSL_SESSION*))
5841 void CyaSSL_CTX_sess_set_remove_cb(CYASSL_CTX* ctx, void (*f)(CYASSL_CTX*,
5849 int CyaSSL_i2d_SSL_SESSION(CYASSL_SESSION* sess, unsigned char** p)
5853 return sizeof(CYASSL_SESSION);
5857 CYASSL_SESSION* CyaSSL_d2i_SSL_SESSION(CYASSL_SESSION** sess,
5858 const unsigned char** p, long i)
5868 long CyaSSL_SESSION_get_timeout(const CYASSL_SESSION* sess)
5870 CYASSL_ENTER("CyaSSL_SESSION_get_timeout");
5871 return sess->timeout;
5875 long CyaSSL_SESSION_get_time(const CYASSL_SESSION* sess)
5877 CYASSL_ENTER("CyaSSL_SESSION_get_time");
5878 return sess->bornOn;
5882 int CyaSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
5893 /* write X509 serial number in unsigned binary to buffer
5894 buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
5895 return 0 on success */
5896 int CyaSSL_X509_get_serial_number(CYASSL_X509* x509, byte* in, int* inOutSz)
5898 CYASSL_ENTER("CyaSSL_X509_get_serial_number");
5899 if (x509 == NULL || in == NULL || *inOutSz < x509->serialSz)
5900 return BAD_FUNC_ARG;
5902 XMEMCPY(in, x509->serial, x509->serialSz);
5903 *inOutSz = x509->serialSz;
5909 const byte* CyaSSL_X509_get_der(CYASSL_X509* x509, int* outSz)
5911 CYASSL_ENTER("CyaSSL_X509_get_der");
5913 if (x509 == NULL || outSz == NULL)
5916 *outSz = (int)x509->derCert.length;
5917 return x509->derCert.buffer;
5921 char* CyaSSL_X509_get_subjectCN(CYASSL_X509* x509)
5926 return x509->subjectCN;
5931 int CyaSSL_cmp_peer_cert_to_file(CYASSL* ssl, const char *fname)
5935 CYASSL_ENTER("CyaSSL_cmp_peer_cert_to_file");
5936 if (ssl != NULL && fname != NULL)
5940 byte staticBuffer[FILE_BUFFER_SIZE];
5941 byte* myBuffer = staticBuffer;
5942 CYASSL_CTX* ctx = ssl->ctx;
5946 CYASSL_X509* peer_cert = &ssl->peerCert;
5953 file = XFOPEN(fname, "rb");
5954 if (!file) return SSL_BAD_FILE;
5955 XFSEEK(file, 0, XSEEK_END);
5958 if (sz > (long)sizeof(staticBuffer)) {
5959 CYASSL_MSG("Getting dynamic buffer");
5960 myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
5963 if ((myBuffer != NULL) &&
5964 (XFREAD(myBuffer, sz, 1, file) > 0) &&
5965 (PemToDer(myBuffer, sz, CERT_TYPE,
5966 &fileDer, ctx->heap, &info, &eccKey) == 0) &&
5967 (fileDer.length != 0) &&
5968 (fileDer.length == peer_cert->derCert.length) &&
5969 (XMEMCMP(peer_cert->derCert.buffer, fileDer.buffer,
5970 fileDer.length) == 0))
5977 XFREE(fileDer.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
5978 if (myBuffer && (myBuffer != staticBuffer))
5979 XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
5985 int CyaSSL_cmp_peer_cert_to_file(CYASSL* ssl, const char *fname)
5994 static RNG globalRNG;
5995 static int initGlobalRNG = 0;
5997 int CyaSSL_RAND_seed(const void* seed, int len)
6000 CYASSL_MSG("CyaSSL_RAND_seed");
6005 if (initGlobalRNG == 0) {
6006 if (InitRng(&globalRNG) < 0) {
6007 CYASSL_MSG("CyaSSL Init Global RNG failed");
6016 int CyaSSL_RAND_bytes(unsigned char* buf, int num)
6021 CYASSL_ENTER("RAND_bytes");
6022 if (InitRng(&tmpRNG) != 0) {
6023 CYASSL_MSG("Bad RNG Init, trying global");
6024 if (initGlobalRNG == 0) {
6025 CYASSL_MSG("Global RNG no Init");
6031 RNG_GenerateBlock(rng, buf, num);
6036 CYASSL_BN_CTX* CyaSSL_BN_CTX_new(void)
6038 static int ctx; /* ctaocrypt doesn't now need ctx */
6040 CYASSL_MSG("CyaSSL_BN_CTX_new");
6042 return (CYASSL_BN_CTX*)&ctx;
6045 void CyaSSL_BN_CTX_init(CYASSL_BN_CTX* ctx)
6048 CYASSL_MSG("CyaSSL_BN_CTX_init");
6052 void CyaSSL_BN_CTX_free(CYASSL_BN_CTX* ctx)
6055 CYASSL_MSG("CyaSSL_BN_CTX_free");
6057 /* do free since static ctx that does nothing */
6061 static void InitCyaSSL_BigNum(CYASSL_BIGNUM* bn)
6063 CYASSL_MSG("InitCyaSSL_BigNum");
6066 bn->internal = NULL;
6071 CYASSL_BIGNUM* CyaSSL_BN_new(void)
6073 CYASSL_BIGNUM* external;
6076 CYASSL_MSG("CyaSSL_BN_new");
6078 mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
6080 CYASSL_MSG("CyaSSL_BN_new malloc mpi failure");
6084 external = (CYASSL_BIGNUM*) XMALLOC(sizeof(CYASSL_BIGNUM), NULL,
6085 DYNAMIC_TYPE_BIGINT);
6086 if (external == NULL) {
6087 CYASSL_MSG("CyaSSL_BN_new malloc CYASSL_BIGNUM failure");
6088 XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
6092 InitCyaSSL_BigNum(external);
6094 external->internal = mpi;
6100 void CyaSSL_BN_free(CYASSL_BIGNUM* bn)
6102 CYASSL_MSG("CyaSSL_BN_free");
6105 mp_clear((mp_int*)bn->internal);
6106 XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
6107 bn->internal = NULL;
6109 XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
6114 void CyaSSL_BN_clear_free(CYASSL_BIGNUM* bn)
6116 CYASSL_MSG("CyaSSL_BN_clear_free");
6122 int CyaSSL_BN_sub(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* a,
6123 const CYASSL_BIGNUM* b)
6125 CYASSL_MSG("CyaSSL_BN_sub");
6127 if (r == NULL || a == NULL || b == NULL)
6130 if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
6131 (mp_int*)r->internal) == MP_OKAY)
6134 CYASSL_MSG("CyaSSL_BN_sub mp_sub failed");
6139 int CyaSSL_BN_mod(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* a,
6140 const CYASSL_BIGNUM* b, const CYASSL_BN_CTX* c)
6143 CYASSL_MSG("CyaSSL_BN_mod");
6145 if (r == NULL || a == NULL || b == NULL)
6148 if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
6149 (mp_int*)r->internal) == MP_OKAY)
6152 CYASSL_MSG("CyaSSL_BN_mod mp_mod failed");
6157 const CYASSL_BIGNUM* CyaSSL_BN_value_one(void)
6159 static CYASSL_BIGNUM* bn_one = NULL;
6161 CYASSL_MSG("CyaSSL_BN_value_one");
6163 if (bn_one == NULL) {
6164 bn_one = CyaSSL_BN_new();
6166 mp_set_int((mp_int*)bn_one->internal, 1);
6173 int CyaSSL_BN_num_bytes(const CYASSL_BIGNUM* bn)
6175 CYASSL_MSG("CyaSSL_BN_num_bytes");
6177 if (bn == NULL || bn->internal == NULL)
6180 return mp_unsigned_bin_size((mp_int*)bn->internal);
6184 int CyaSSL_BN_num_bits(const CYASSL_BIGNUM* bn)
6186 CYASSL_MSG("CyaSSL_BN_num_bits");
6188 if (bn == NULL || bn->internal == NULL)
6191 return mp_count_bits((mp_int*)bn->internal);
6195 int CyaSSL_BN_is_zero(const CYASSL_BIGNUM* bn)
6197 CYASSL_MSG("CyaSSL_BN_is_zero");
6199 if (bn == NULL || bn->internal == NULL)
6202 return mp_iszero((mp_int*)bn->internal);
6206 int CyaSSL_BN_is_one(const CYASSL_BIGNUM* bn)
6208 CYASSL_MSG("CyaSSL_BN_is_one");
6210 if (bn == NULL || bn->internal == NULL)
6213 if (mp_cmp_d((mp_int*)bn->internal, 1) == 0)
6220 int CyaSSL_BN_is_odd(const CYASSL_BIGNUM* bn)
6222 CYASSL_MSG("CyaSSL_BN_is_odd");
6224 if (bn == NULL || bn->internal == NULL)
6227 return mp_isodd((mp_int*)bn->internal);
6231 int CyaSSL_BN_cmp(const CYASSL_BIGNUM* a, const CYASSL_BIGNUM* b)
6233 CYASSL_MSG("CyaSSL_BN_cmp");
6235 if (a == NULL || a->internal == NULL || b == NULL || b->internal ==NULL)
6238 return mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
6242 int CyaSSL_BN_bn2bin(const CYASSL_BIGNUM* bn, unsigned char* r)
6244 CYASSL_MSG("CyaSSL_BN_bn2bin");
6246 if (bn == NULL || bn->internal == NULL) {
6247 CYASSL_MSG("NULL bn error");
6252 return mp_unsigned_bin_size((mp_int*)bn->internal);
6254 if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
6255 CYASSL_MSG("mp_to_unsigned_bin error");
6259 return mp_unsigned_bin_size((mp_int*)bn->internal);
6263 CYASSL_BIGNUM* CyaSSL_BN_bin2bn(const unsigned char* str, int len,
6266 CYASSL_MSG("CyaSSL_BN_bin2bn");
6268 if (ret && ret->internal) {
6269 if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
6270 CYASSL_MSG("mp_read_unsigned_bin failure");
6275 CYASSL_MSG("CyaSSL_BN_bin2bn wants return bignum");
6282 int CyaSSL_mask_bits(CYASSL_BIGNUM* bn, int n)
6286 CYASSL_MSG("CyaSSL_BN_mask_bits");
6292 int CyaSSL_BN_rand(CYASSL_BIGNUM* bn, int bits, int top, int bottom)
6302 CYASSL_MSG("CyaSSL_BN_rand");
6304 if (bn == NULL || bn->internal == NULL) {
6305 CYASSL_MSG("Bad function arguments");
6312 if ( (ret = InitRng(&tmpRNG)) != 0) {
6313 CYASSL_MSG("Bad RNG Init, trying global");
6314 if (initGlobalRNG == 0) {
6315 CYASSL_MSG("Global RNG no Init");
6321 RNG_GenerateBlock(rng, buff, len);
6322 buff[0] |= 0x80 | 0x40;
6323 buff[len-1] |= 0x01;
6325 if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY) {
6326 CYASSL_MSG("mp read bin failed");
6334 int CyaSSL_BN_is_bit_set(const CYASSL_BIGNUM* bn, int n)
6339 CYASSL_MSG("CyaSSL_BN_is_bit_set");
6345 int CyaSSL_BN_hex2bn(CYASSL_BIGNUM** bn, const char* str)
6348 word32 decSz = sizeof(decoded);
6350 CYASSL_MSG("CyaSSL_BN_hex2bn");
6353 CYASSL_MSG("Bad function argument");
6357 if (Base16_Decode((byte*)str, strlen(str), decoded, &decSz) < 0) {
6358 CYASSL_MSG("Bad Base16_Decode error");
6366 *bn = CyaSSL_BN_new();
6368 CYASSL_MSG("BN new failed");
6373 if (CyaSSL_BN_bin2bn(decoded, decSz, *bn) == NULL) {
6374 CYASSL_MSG("Bad bin2bn error");
6378 return 1; /* success */
6382 CYASSL_BIGNUM* CyaSSL_BN_dup(const CYASSL_BIGNUM* bn)
6386 CYASSL_MSG("CyaSSL_BN_dup");
6388 if (bn == NULL || bn->internal == NULL) {
6389 CYASSL_MSG("bn NULL error");
6393 ret = CyaSSL_BN_new();
6395 CYASSL_MSG("bn new error");
6399 if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
6400 CYASSL_MSG("mp_copy error");
6401 CyaSSL_BN_free(ret);
6409 CYASSL_BIGNUM* CyaSSL_BN_copy(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* bn)
6414 CYASSL_MSG("CyaSSL_BN_copy");
6420 int CyaSSL_BN_set_word(CYASSL_BIGNUM* bn, unsigned long w)
6425 CYASSL_MSG("CyaSSL_BN_set_word");
6431 int CyaSSL_BN_dec2bn(CYASSL_BIGNUM** bn, const char* str)
6436 CYASSL_MSG("CyaSSL_BN_dec2bn");
6442 char* CyaSSL_BN_bn2dec(const CYASSL_BIGNUM* bn)
6446 CYASSL_MSG("CyaSSL_BN_bn2dec");
6452 static void InitCyaSSL_DH(CYASSL_DH* dh)
6458 dh->priv_key = NULL;
6459 dh->internal = NULL;
6466 CYASSL_DH* CyaSSL_DH_new(void)
6468 CYASSL_DH* external;
6471 CYASSL_MSG("CyaSSL_DH_new");
6473 key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
6475 CYASSL_MSG("CyaSSL_DH_new malloc DhKey failure");
6479 external = (CYASSL_DH*) XMALLOC(sizeof(CYASSL_DH), NULL,
6481 if (external == NULL) {
6482 CYASSL_MSG("CyaSSL_DH_new malloc CYASSL_DH failure");
6483 XFREE(key, NULL, DYNAMIC_TYPE_DH);
6487 InitCyaSSL_DH(external);
6489 external->internal = key;
6495 void CyaSSL_DH_free(CYASSL_DH* dh)
6497 CYASSL_MSG("CyaSSL_DH_free");
6501 FreeDhKey((DhKey*)dh->internal);
6502 XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
6503 dh->internal = NULL;
6505 CyaSSL_BN_free(dh->priv_key);
6506 CyaSSL_BN_free(dh->pub_key);
6507 CyaSSL_BN_free(dh->g);
6508 CyaSSL_BN_free(dh->p);
6509 InitCyaSSL_DH(dh); /* set back to NULLs for safety */
6511 XFREE(dh, NULL, DYNAMIC_TYPE_DH);
6516 static int SetDhInternal(CYASSL_DH* dh)
6518 unsigned char p[1024];
6519 unsigned char g[1024];
6520 int pSz = sizeof(p);
6521 int gSz = sizeof(g);
6523 CYASSL_ENTER("SetDhInternal");
6525 if (dh == NULL || dh->p == NULL || dh->g == NULL) {
6526 CYASSL_MSG("Bad function arguments");
6530 if (CyaSSL_BN_bn2bin(dh->p, NULL) > pSz) {
6531 CYASSL_MSG("Bad p internal size");
6535 if (CyaSSL_BN_bn2bin(dh->g, NULL) > gSz) {
6536 CYASSL_MSG("Bad g internal size");
6540 pSz = CyaSSL_BN_bn2bin(dh->p, p);
6541 gSz = CyaSSL_BN_bn2bin(dh->g, g);
6543 if (pSz <= 0 || gSz <= 0) {
6544 CYASSL_MSG("Bad BN2bin set");
6548 if (DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0) {
6549 CYASSL_MSG("Bad DH SetKey");
6559 int CyaSSL_DH_size(CYASSL_DH* dh)
6561 CYASSL_MSG("CyaSSL_DH_size");
6566 return CyaSSL_BN_num_bytes(dh->p);
6570 /* return 1 on success else 0 */
6571 int CyaSSL_DH_generate_key(CYASSL_DH* dh)
6573 unsigned char pub [1024];
6574 unsigned char priv[1024];
6575 word32 pubSz = sizeof(pub);
6576 word32 privSz = sizeof(priv);
6581 CYASSL_MSG("CyaSSL_DH_generate_key");
6583 if (dh == NULL || dh->p == NULL || dh->g == NULL) {
6584 CYASSL_MSG("Bad function arguments");
6588 if (dh->inSet == 0) {
6589 if (SetDhInternal(dh) < 0) {
6590 CYASSL_MSG("Bad DH set internal");
6595 if ( (ret = InitRng(&tmpRNG)) != 0) {
6596 CYASSL_MSG("Bad RNG Init, trying global");
6597 if (initGlobalRNG == 0) {
6598 CYASSL_MSG("Global RNG no Init");
6604 if (DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
6606 CYASSL_MSG("Bad DhGenerateKeyPair");
6611 CyaSSL_BN_free(dh->pub_key);
6612 dh->pub_key = CyaSSL_BN_new();
6613 if (dh->pub_key == NULL) {
6614 CYASSL_MSG("Bad DH new pub");
6619 CyaSSL_BN_free(dh->priv_key);
6620 dh->priv_key = CyaSSL_BN_new();
6621 if (dh->priv_key == NULL) {
6622 CYASSL_MSG("Bad DH new priv");
6626 if (CyaSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL) {
6627 CYASSL_MSG("Bad DH bn2bin error pub");
6631 if (CyaSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL) {
6632 CYASSL_MSG("Bad DH bn2bin error priv");
6636 CYASSL_MSG("CyaSSL_generate_key success");
6641 /* return 1 on success, 0 otherwise */
6642 int CyaSSL_DH_compute_key(unsigned char* key, CYASSL_BIGNUM* otherPub,
6645 unsigned char pub [1024];
6646 unsigned char priv[1024];
6647 word32 pubSz = sizeof(pub);
6648 word32 privSz = sizeof(priv);
6651 CYASSL_MSG("CyaSSL_DH_compute_key");
6653 if (dh == NULL || dh->priv_key == NULL || otherPub == NULL) {
6654 CYASSL_MSG("Bad function arguments");
6658 keySz = (word32)DH_size(dh);
6660 CYASSL_MSG("Bad DH_size");
6664 if (CyaSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz) {
6665 CYASSL_MSG("Bad priv internal size");
6669 if (CyaSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz) {
6670 CYASSL_MSG("Bad otherPub size");
6674 privSz = CyaSSL_BN_bn2bin(dh->priv_key, priv);
6675 pubSz = CyaSSL_BN_bn2bin(otherPub, pub);
6677 if (privSz <= 0 || pubSz <= 0) {
6678 CYASSL_MSG("Bad BN2bin set");
6682 if (DhAgree((DhKey*)dh->internal, key, &keySz, priv, privSz, pub,
6684 CYASSL_MSG("DhAgree failed");
6688 CYASSL_MSG("CyaSSL_compute_key success");
6693 static void InitCyaSSL_DSA(CYASSL_DSA* dsa)
6699 dsa->pub_key = NULL;
6700 dsa->priv_key = NULL;
6701 dsa->internal = NULL;
6708 CYASSL_DSA* CyaSSL_DSA_new(void)
6710 CYASSL_DSA* external;
6713 CYASSL_MSG("CyaSSL_DSA_new");
6715 key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
6717 CYASSL_MSG("CyaSSL_DSA_new malloc DsaKey failure");
6721 external = (CYASSL_DSA*) XMALLOC(sizeof(CYASSL_DSA), NULL,
6723 if (external == NULL) {
6724 CYASSL_MSG("CyaSSL_DSA_new malloc CYASSL_DSA failure");
6725 XFREE(key, NULL, DYNAMIC_TYPE_DSA);
6729 InitCyaSSL_DSA(external);
6731 external->internal = key;
6737 void CyaSSL_DSA_free(CYASSL_DSA* dsa)
6739 CYASSL_MSG("CyaSSL_DSA_free");
6742 if (dsa->internal) {
6743 FreeDsaKey((DsaKey*)dsa->internal);
6744 XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
6745 dsa->internal = NULL;
6747 CyaSSL_BN_free(dsa->priv_key);
6748 CyaSSL_BN_free(dsa->pub_key);
6749 CyaSSL_BN_free(dsa->g);
6750 CyaSSL_BN_free(dsa->q);
6751 CyaSSL_BN_free(dsa->p);
6752 InitCyaSSL_DSA(dsa); /* set back to NULLs for safety */
6754 XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
6759 int CyaSSL_DSA_generate_key(CYASSL_DSA* dsa)
6763 CYASSL_MSG("CyaSSL_DSA_generate_key");
6765 return 0; /* key gen not needed by server */
6769 int CyaSSL_DSA_generate_parameters_ex(CYASSL_DSA* dsa, int bits,
6770 unsigned char* seed, int seedLen, int* counterRet,
6771 unsigned long* hRet, void* cb)
6781 CYASSL_MSG("CyaSSL_DSA_generate_parameters_ex");
6783 return 0; /* key gen not needed by server */
6787 static void InitCyaSSL_Rsa(CYASSL_RSA* rsa)
6798 rsa->internal = NULL;
6805 CYASSL_RSA* CyaSSL_RSA_new(void)
6807 CYASSL_RSA* external;
6810 CYASSL_MSG("CyaSSL_RSA_new");
6812 key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
6814 CYASSL_MSG("CyaSSL_RSA_new malloc RsaKey failure");
6818 external = (CYASSL_RSA*) XMALLOC(sizeof(CYASSL_RSA), NULL,
6820 if (external == NULL) {
6821 CYASSL_MSG("CyaSSL_RSA_new malloc CYASSL_RSA failure");
6822 XFREE(key, NULL, DYNAMIC_TYPE_RSA);
6826 InitCyaSSL_Rsa(external);
6827 InitRsaKey(key, NULL);
6828 external->internal = key;
6834 void CyaSSL_RSA_free(CYASSL_RSA* rsa)
6836 CYASSL_MSG("CyaSSL_RSA_free");
6839 if (rsa->internal) {
6840 FreeRsaKey((RsaKey*)rsa->internal);
6841 XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
6842 rsa->internal = NULL;
6844 CyaSSL_BN_free(rsa->iqmp);
6845 CyaSSL_BN_free(rsa->dmq1);
6846 CyaSSL_BN_free(rsa->dmp1);
6847 CyaSSL_BN_free(rsa->q);
6848 CyaSSL_BN_free(rsa->p);
6849 CyaSSL_BN_free(rsa->d);
6850 CyaSSL_BN_free(rsa->e);
6851 CyaSSL_BN_free(rsa->n);
6852 InitCyaSSL_Rsa(rsa); /* set back to NULLs for safety */
6854 XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
6859 static int SetIndividualExternal(CYASSL_BIGNUM** bn, mp_int* mpi)
6861 CYASSL_MSG("Entering SetIndividualExternal");
6864 CYASSL_MSG("mpi NULL error");
6869 *bn = CyaSSL_BN_new();
6871 CYASSL_MSG("SetIndividualExternal alloc failed");
6876 if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
6877 CYASSL_MSG("mp_copy error");
6885 static int SetDsaExternal(CYASSL_DSA* dsa)
6888 CYASSL_MSG("Entering SetDsaExternal");
6890 if (dsa == NULL || dsa->internal == NULL) {
6891 CYASSL_MSG("dsa key NULL error");
6895 key = (DsaKey*)dsa->internal;
6897 if (SetIndividualExternal(&dsa->p, &key->p) < 0) {
6898 CYASSL_MSG("dsa p key error");
6902 if (SetIndividualExternal(&dsa->q, &key->q) < 0) {
6903 CYASSL_MSG("dsa q key error");
6907 if (SetIndividualExternal(&dsa->g, &key->g) < 0) {
6908 CYASSL_MSG("dsa g key error");
6912 if (SetIndividualExternal(&dsa->pub_key, &key->y) < 0) {
6913 CYASSL_MSG("dsa y key error");
6917 if (SetIndividualExternal(&dsa->priv_key, &key->x) < 0) {
6918 CYASSL_MSG("dsa x key error");
6928 static int SetRsaExternal(CYASSL_RSA* rsa)
6931 CYASSL_MSG("Entering SetRsaExternal");
6933 if (rsa == NULL || rsa->internal == NULL) {
6934 CYASSL_MSG("rsa key NULL error");
6938 key = (RsaKey*)rsa->internal;
6940 if (SetIndividualExternal(&rsa->n, &key->n) < 0) {
6941 CYASSL_MSG("rsa n key error");
6945 if (SetIndividualExternal(&rsa->e, &key->e) < 0) {
6946 CYASSL_MSG("rsa e key error");
6950 if (SetIndividualExternal(&rsa->d, &key->d) < 0) {
6951 CYASSL_MSG("rsa d key error");
6955 if (SetIndividualExternal(&rsa->p, &key->p) < 0) {
6956 CYASSL_MSG("rsa p key error");
6960 if (SetIndividualExternal(&rsa->q, &key->q) < 0) {
6961 CYASSL_MSG("rsa q key error");
6965 if (SetIndividualExternal(&rsa->dmp1, &key->dP) < 0) {
6966 CYASSL_MSG("rsa dP key error");
6970 if (SetIndividualExternal(&rsa->dmq1, &key->dQ) < 0) {
6971 CYASSL_MSG("rsa dQ key error");
6975 if (SetIndividualExternal(&rsa->iqmp, &key->u) < 0) {
6976 CYASSL_MSG("rsa u key error");
6986 int CyaSSL_RSA_generate_key_ex(CYASSL_RSA* rsa, int bits, CYASSL_BIGNUM* bn,
6991 CYASSL_MSG("CyaSSL_RSA_generate_key_ex");
6998 if (InitRng(&rng) < 0) {
6999 CYASSL_MSG("RNG init failed");
7003 #ifdef CYASSL_KEY_GEN
7004 if (MakeRsaKey((RsaKey*)rsa->internal, bits, 65537, &rng) < 0) {
7005 CYASSL_MSG("MakeRsaKey failed");
7009 if (SetRsaExternal(rsa) < 0) {
7010 CYASSL_MSG("SetRsaExternal failed");
7016 return 1; /* success */
7018 CYASSL_MSG("No Key Gen built in");
7025 int CyaSSL_RSA_blinding_on(CYASSL_RSA* rsa, CYASSL_BN_CTX* bn)
7030 CYASSL_MSG("CyaSSL_RSA_blinding_on");
7032 return 1; /* on by default */
7036 int CyaSSL_RSA_public_encrypt(int len, unsigned char* fr,
7037 unsigned char* to, CYASSL_RSA* rsa, int padding)
7045 CYASSL_MSG("CyaSSL_RSA_public_encrypt");
7051 int CyaSSL_RSA_private_decrypt(int len, unsigned char* fr,
7052 unsigned char* to, CYASSL_RSA* rsa, int padding)
7060 CYASSL_MSG("CyaSSL_RSA_private_decrypt");
7066 int CyaSSL_RSA_size(const CYASSL_RSA* rsa)
7068 CYASSL_MSG("CyaSSL_RSA_size");
7073 return CyaSSL_BN_num_bytes(rsa->n);
7077 /* return 0 on success, < 0 otherwise */
7078 int CyaSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
7084 CYASSL_MSG("CyaSSL_DSA_do_sign");
7086 if (d == NULL || sigRet == NULL || dsa == NULL) {
7087 CYASSL_MSG("Bad function arguments");
7091 if (dsa->inSet == 0) {
7092 CYASSL_MSG("No DSA internal set");
7096 if (InitRng(&tmpRNG) != 0) {
7097 CYASSL_MSG("Bad RNG Init, trying global");
7098 if (initGlobalRNG == 0) {
7099 CYASSL_MSG("Global RNG no Init");
7105 if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
7106 CYASSL_MSG("DsaSign failed");
7114 /* return 1 on success, 0 otherwise */
7115 int CyaSSL_RSA_sign(int type, const unsigned char* m,
7116 unsigned int mLen, unsigned char* sigRet,
7117 unsigned int* sigLen, CYASSL_RSA* rsa)
7119 byte encodedSig[MAX_ENCODED_SIG_SZ];
7125 CYASSL_MSG("CyaSSL_RSA_sign");
7127 if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL) {
7128 CYASSL_MSG("Bad function arguments");
7132 if (rsa->inSet == 0) {
7133 CYASSL_MSG("No RSA internal set");
7137 outLen = (word32)CyaSSL_BN_num_bytes(rsa->n);
7139 CYASSL_MSG("Bad RSA size");
7143 if (InitRng(&tmpRNG) != 0) {
7144 CYASSL_MSG("Bad RNG Init, trying global");
7145 if (initGlobalRNG == 0) {
7146 CYASSL_MSG("Global RNG no Init");
7162 CYASSL_MSG("Bad md type");
7166 signSz = EncodeSignature(encodedSig, m, mLen, type);
7168 CYASSL_MSG("Bad Encode Signature");
7172 *sigLen = RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
7173 (RsaKey*)rsa->internal, rng);
7175 CYASSL_MSG("Bad Rsa Sign");
7179 CYASSL_MSG("CyaSSL_RSA_sign success");
7180 return 1; /* success */
7184 int CyaSSL_RSA_public_decrypt(int flen, unsigned char* from,
7185 unsigned char* to, CYASSL_RSA* rsa, int padding)
7193 CYASSL_MSG("CyaSSL_RSA_public_decrypt");
7199 /* generate p-1 and q-1 */
7200 int CyaSSL_RSA_GenAdd(CYASSL_RSA* rsa)
7205 CYASSL_MSG("CyaSSL_RsaGenAdd");
7207 if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
7208 rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
7209 CYASSL_MSG("rsa no init error");
7213 if (mp_init(&tmp) != MP_OKAY) {
7214 CYASSL_MSG("mp_init error");
7218 err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
7220 CYASSL_MSG("mp_sub_d error");
7222 err = mp_mod((mp_int*)rsa->d->internal, &tmp,
7223 (mp_int*)rsa->dmp1->internal);
7226 CYASSL_MSG("mp_mod error");
7228 err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
7230 CYASSL_MSG("mp_sub_d error");
7232 err = mp_mod((mp_int*)rsa->d->internal, &tmp,
7233 (mp_int*)rsa->dmq1->internal);
7244 void CyaSSL_HMAC_Init(CYASSL_HMAC_CTX* ctx, const void* key, int keylen,
7247 CYASSL_MSG("CyaSSL_HMAC_Init");
7250 CYASSL_MSG("no ctx on init");
7255 CYASSL_MSG("init has type");
7257 if (XSTRNCMP(type, "MD5", 3) == 0) {
7258 CYASSL_MSG("md5 hmac");
7261 else if (XSTRNCMP(type, "SHA256", 6) == 0) {
7262 CYASSL_MSG("sha256 hmac");
7266 /* has to be last since would pick or 256, 384, or 512 too */
7267 else if (XSTRNCMP(type, "SHA", 3) == 0) {
7268 CYASSL_MSG("sha hmac");
7272 CYASSL_MSG("bad init type");
7276 if (key && keylen) {
7277 CYASSL_MSG("keying hmac");
7278 HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen);
7283 void CyaSSL_HMAC_Update(CYASSL_HMAC_CTX* ctx, const unsigned char* data,
7286 CYASSL_MSG("CyaSSL_HMAC_Update");
7289 CYASSL_MSG("updating hmac");
7290 HmacUpdate(&ctx->hmac, data, (word32)len);
7295 void CyaSSL_HMAC_Final(CYASSL_HMAC_CTX* ctx, unsigned char* hash,
7298 CYASSL_MSG("CyaSSL_HMAC_Final");
7301 CYASSL_MSG("final hmac");
7302 HmacFinal(&ctx->hmac, hash);
7305 CYASSL_MSG("setting output len");
7306 switch (ctx->type) {
7308 *len = MD5_DIGEST_SIZE;
7312 *len = SHA_DIGEST_SIZE;
7316 *len = SHA256_DIGEST_SIZE;
7320 CYASSL_MSG("bad hmac type");
7327 void CyaSSL_HMAC_cleanup(CYASSL_HMAC_CTX* ctx)
7331 CYASSL_MSG("CyaSSL_HMAC_cleanup");
7335 const CYASSL_EVP_MD* CyaSSL_EVP_get_digestbynid(int id)
7337 CYASSL_MSG("CyaSSL_get_digestbynid");
7341 return CyaSSL_EVP_md5();
7345 return CyaSSL_EVP_sha1();
7349 CYASSL_MSG("Bad digest id value");
7356 CYASSL_RSA* CyaSSL_EVP_PKEY_get1_RSA(CYASSL_EVP_PKEY* key)
7359 CYASSL_MSG("CyaSSL_EVP_PKEY_get1_RSA");
7365 CYASSL_DSA* CyaSSL_EVP_PKEY_get1_DSA(CYASSL_EVP_PKEY* key)
7368 CYASSL_MSG("CyaSSL_EVP_PKEY_get1_DSA");
7374 void* CyaSSL_EVP_X_STATE(const CYASSL_EVP_CIPHER_CTX* ctx)
7376 CYASSL_MSG("CyaSSL_EVP_X_STATE");
7379 switch (ctx->cipherType) {
7381 CYASSL_MSG("returning arc4 state");
7382 return (void*)&ctx->cipher.arc4.x;
7386 CYASSL_MSG("bad x state type");
7395 int CyaSSL_EVP_X_STATE_LEN(const CYASSL_EVP_CIPHER_CTX* ctx)
7397 CYASSL_MSG("CyaSSL_EVP_X_STATE_LEN");
7400 switch (ctx->cipherType) {
7402 CYASSL_MSG("returning arc4 state size");
7403 return sizeof(Arc4);
7407 CYASSL_MSG("bad x state type");
7416 void CyaSSL_3des_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset,
7417 unsigned char* iv, int len)
7421 CYASSL_MSG("CyaSSL_3des_iv");
7423 if (ctx == NULL || iv == NULL) {
7424 CYASSL_MSG("Bad function argument");
7429 Des3_SetIV(&ctx->cipher.des3, iv);
7431 memcpy(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
7435 void CyaSSL_aes_ctr_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset,
7436 unsigned char* iv, int len)
7440 CYASSL_MSG("CyaSSL_aes_ctr_iv");
7442 if (ctx == NULL || iv == NULL) {
7443 CYASSL_MSG("Bad function argument");
7448 AesSetIV(&ctx->cipher.aes, iv);
7450 memcpy(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
7454 const CYASSL_EVP_MD* CyaSSL_EVP_ripemd160(void)
7456 CYASSL_MSG("CyaSSL_ripemd160");
7462 int CyaSSL_EVP_MD_size(const CYASSL_EVP_MD* type)
7464 CYASSL_MSG("CyaSSL_EVP_MD_size");
7467 CYASSL_MSG("No md type arg");
7468 return BAD_FUNC_ARG;
7471 if (XSTRNCMP(type, "MD5", 3) == 0) {
7472 return MD5_DIGEST_SIZE;
7474 else if (XSTRNCMP(type, "SHA256", 6) == 0) {
7475 return SHA256_DIGEST_SIZE;
7477 #ifdef CYASSL_SHA384
7478 else if (XSTRNCMP(type, "SHA384", 6) == 0) {
7479 return SHA384_DIGEST_SIZE;
7482 #ifdef CYASSL_SHA512
7483 else if (XSTRNCMP(type, "SHA512", 6) == 0) {
7484 return SHA512_DIGEST_SIZE;
7487 /* has to be last since would pick or 256, 384, or 512 too */
7488 else if (XSTRNCMP(type, "SHA", 3) == 0) {
7489 return SHA_DIGEST_SIZE;
7492 return BAD_FUNC_ARG;
7496 int CyaSSL_EVP_CIPHER_CTX_iv_length(const CYASSL_EVP_CIPHER_CTX* ctx)
7498 CYASSL_MSG("CyaSSL_EVP_CIPHER_CTX_iv_length");
7500 switch (ctx->cipherType) {
7502 case AES_128_CBC_TYPE :
7503 case AES_192_CBC_TYPE :
7504 case AES_256_CBC_TYPE :
7505 CYASSL_MSG("AES CBC");
7506 return AES_BLOCK_SIZE;
7509 #ifdef CYASSL_AES_COUNTER
7510 case AES_128_CTR_TYPE :
7511 case AES_192_CTR_TYPE :
7512 case AES_256_CTR_TYPE :
7513 CYASSL_MSG("AES CTR");
7514 return AES_BLOCK_SIZE;
7519 CYASSL_MSG("DES CBC");
7520 return DES_BLOCK_SIZE;
7523 case DES_EDE3_CBC_TYPE :
7524 CYASSL_MSG("DES EDE3 CBC");
7525 return DES_BLOCK_SIZE;
7533 case NULL_CIPHER_TYPE :
7539 CYASSL_MSG("bad type");
7546 void CyaSSL_OPENSSL_free(void* p)
7548 CYASSL_MSG("CyaSSL_OPENSSL_free");
7554 int CyaSSL_PEM_write_bio_RSAPrivateKey(CYASSL_BIO* bio, RSA* rsa,
7555 const EVP_CIPHER* cipher,
7556 unsigned char* passwd, int len,
7557 pem_password_cb cb, void* arg)
7567 CYASSL_MSG("CyaSSL_PEM_write_bio_RSAPrivateKey");
7574 int CyaSSL_PEM_write_bio_DSAPrivateKey(CYASSL_BIO* bio, DSA* rsa,
7575 const EVP_CIPHER* cipher,
7576 unsigned char* passwd, int len,
7577 pem_password_cb cb, void* arg)
7587 CYASSL_MSG("CyaSSL_PEM_write_bio_DSAPrivateKey");
7594 CYASSL_EVP_PKEY* CyaSSL_PEM_read_bio_PrivateKey(CYASSL_BIO* bio,
7595 CYASSL_EVP_PKEY** key, pem_password_cb cb, void* arg)
7602 CYASSL_MSG("CyaSSL_PEM_read_bio_PrivateKey");
7609 /* Return bytes written to buff or < 0 for error */
7610 int CyaSSL_KeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff,
7611 int buffSz, const char* pass)
7620 CYASSL_ENTER("CyaSSL_KeyPemToDer");
7622 if (pem == NULL || buff == NULL || buffSz <= 0) {
7623 CYASSL_MSG("Bad pem der args");
7624 return BAD_FUNC_ARG;
7632 ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, &info, &eccKey);
7634 CYASSL_MSG("Bad Pem To Der");
7637 if (der.length <= (word32)buffSz) {
7638 XMEMCPY(buff, der.buffer, der.length);
7642 CYASSL_MSG("Bad der length");
7647 XFREE(der.buffer, NULL, DYANMIC_KEY_TYPE);
7653 /* Load RSA from Der, 0 on success < 0 on error */
7654 int CyaSSL_RSA_LoadDer(CYASSL_RSA* rsa, const unsigned char* der, int derSz)
7659 CYASSL_ENTER("CyaSSL_RSA_LoadDer");
7661 if (rsa == NULL || rsa->internal == NULL || der == NULL || derSz <= 0) {
7662 CYASSL_MSG("Bad function arguments");
7663 return BAD_FUNC_ARG;
7666 ret = RsaPrivateKeyDecode(der, &idx, (RsaKey*)rsa->internal, derSz);
7668 CYASSL_MSG("RsaPrivateKeyDecode failed");
7672 if (SetRsaExternal(rsa) < 0) {
7673 CYASSL_MSG("SetRsaExternal failed");
7683 /* Load DSA from Der, 0 on success < 0 on error */
7684 int CyaSSL_DSA_LoadDer(CYASSL_DSA* dsa, const unsigned char* der, int derSz)
7689 CYASSL_ENTER("CyaSSL_DSA_LoadDer");
7691 if (dsa == NULL || dsa->internal == NULL || der == NULL || derSz <= 0) {
7692 CYASSL_MSG("Bad function arguments");
7693 return BAD_FUNC_ARG;
7696 ret = DsaPrivateKeyDecode(der, &idx, (DsaKey*)dsa->internal, derSz);
7698 CYASSL_MSG("DsaPrivateKeyDecode failed");
7702 if (SetDsaExternal(dsa) < 0) {
7703 CYASSL_MSG("SetDsaExternal failed");
7716 #endif /* OPENSSL_EXTRA */
7719 #ifdef SESSION_CERTS
7722 /* Get peer's certificate chain */
7723 CYASSL_X509_CHAIN* CyaSSL_get_peer_chain(CYASSL* ssl)
7725 CYASSL_ENTER("CyaSSL_get_peer_chain");
7727 return &ssl->session.chain;
7733 /* Get peer's certificate chain total count */
7734 int CyaSSL_get_chain_count(CYASSL_X509_CHAIN* chain)
7736 CYASSL_ENTER("CyaSSL_get_chain_count");
7738 return chain->count;
7744 /* Get peer's ASN.1 DER ceritifcate at index (idx) length in bytes */
7745 int CyaSSL_get_chain_length(CYASSL_X509_CHAIN* chain, int idx)
7747 CYASSL_ENTER("CyaSSL_get_chain_length");
7749 return chain->certs[idx].length;
7755 /* Get peer's ASN.1 DER ceritifcate at index (idx) */
7756 byte* CyaSSL_get_chain_cert(CYASSL_X509_CHAIN* chain, int idx)
7758 CYASSL_ENTER("CyaSSL_get_chain_cert");
7760 return chain->certs[idx].buffer;
7766 /* Get peer's PEM ceritifcate at index (idx), output to buffer if inLen big
7767 enough else return error (-1), output length is in *outLen */
7768 int CyaSSL_get_chain_cert_pem(CYASSL_X509_CHAIN* chain, int idx,
7769 unsigned char* buf, int inLen, int* outLen)
7771 const char header[] = "-----BEGIN CERTIFICATE-----\n";
7772 const char footer[] = "-----END CERTIFICATE-----\n";
7774 int headerLen = sizeof(header) - 1;
7775 int footerLen = sizeof(footer) - 1;
7779 CYASSL_ENTER("CyaSSL_get_chain_cert_pem");
7780 if (!chain || !outLen || !buf)
7781 return BAD_FUNC_ARG;
7783 /* don't even try if inLen too short */
7784 if (inLen < headerLen + footerLen + chain->certs[idx].length)
7785 return BAD_FUNC_ARG;
7788 XMEMCPY(buf, header, headerLen);
7792 *outLen = inLen; /* input to Base64_Encode */
7793 if ( (err = Base64_Encode(chain->certs[idx].buffer,
7794 chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
7799 if ( (i + footerLen) > inLen)
7800 return BAD_FUNC_ARG;
7801 XMEMCPY(buf + i, footer, footerLen);
7802 *outLen += headerLen + footerLen;
7808 /* get session ID */
7809 const byte* CyaSSL_get_sessionID(const CYASSL_SESSION* session)
7811 CYASSL_ENTER("CyaSSL_get_sessionID");
7813 return session->sessionID;
7819 #endif /* SESSION_CERTS */
7822 long CyaSSL_CTX_OCSP_set_options(CYASSL_CTX* ctx, long options)
7824 CYASSL_ENTER("CyaSSL_CTX_OCSP_set_options");
7827 ctx->ocsp.enabled = (options & CYASSL_OCSP_ENABLE) != 0;
7828 ctx->ocsp.useOverrideUrl = (options & CYASSL_OCSP_URL_OVERRIDE) != 0;
7835 return NOT_COMPILED_IN;
7840 int CyaSSL_CTX_OCSP_set_override_url(CYASSL_CTX* ctx, const char* url)
7842 CYASSL_ENTER("CyaSSL_CTX_OCSP_set_override_url");
7844 return CyaSSL_OCSP_set_override_url(&ctx->ocsp, url);
7848 return NOT_COMPILED_IN;