summaryrefslogtreecommitdiffstats
path: root/lib/libssl/src/ssl
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2012-10-13 21:23:32 +0000
committerdjm <djm@openbsd.org>2012-10-13 21:23:32 +0000
commitec07fdf13572372e9cd617b18f2e2790e6616c8c (patch)
treebc2aaa935cf216bb82963cd07e6b9f736c4cb1e7 /lib/libssl/src/ssl
parentsync (diff)
downloadwireguard-openbsd-ec07fdf13572372e9cd617b18f2e2790e6616c8c.tar.xz
wireguard-openbsd-ec07fdf13572372e9cd617b18f2e2790e6616c8c.zip
import OpenSSL-1.0.1c
Diffstat (limited to 'lib/libssl/src/ssl')
-rw-r--r--lib/libssl/src/ssl/d1_both.c178
-rw-r--r--lib/libssl/src/ssl/d1_enc.c2
-rw-r--r--lib/libssl/src/ssl/d1_lib.c54
-rw-r--r--lib/libssl/src/ssl/d1_srtp.c493
-rwxr-xr-xlib/libssl/src/ssl/install-ssl.com2
-rw-r--r--lib/libssl/src/ssl/srtp.h145
-rw-r--r--lib/libssl/src/ssl/tls_srp.c506
7 files changed, 1364 insertions, 16 deletions
diff --git a/lib/libssl/src/ssl/d1_both.c b/lib/libssl/src/ssl/d1_both.c
index 9f898d69978..de8bab873f2 100644
--- a/lib/libssl/src/ssl/d1_both.c
+++ b/lib/libssl/src/ssl/d1_both.c
@@ -227,14 +227,14 @@ int dtls1_do_write(SSL *s, int type)
unsigned int len, frag_off, mac_size, blocksize;
/* AHA! Figure out the MTU, and stick to the right size */
- if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
+ if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
{
s->d1->mtu =
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
/* I've seen the kernel return bogus numbers when it doesn't know
* (initial write), so just make sure we have a reasonable number */
- if ( s->d1->mtu < dtls1_min_mtu())
+ if (s->d1->mtu < dtls1_min_mtu())
{
s->d1->mtu = 0;
s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
@@ -1084,7 +1084,11 @@ int dtls1_read_failed(SSL *s, int code)
return code;
}
- if ( ! SSL_in_init(s)) /* done, no need to send a retransmit */
+#ifndef OPENSSL_NO_HEARTBEATS
+ if (!SSL_in_init(s) && !s->tlsext_hb_pending) /* done, no need to send a retransmit */
+#else
+ if (!SSL_in_init(s)) /* done, no need to send a retransmit */
+#endif
{
BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
return code;
@@ -1417,3 +1421,171 @@ dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
ccs_hdr->type = *(data++);
}
+
+int dtls1_shutdown(SSL *s)
+ {
+ int ret;
+#ifndef OPENSSL_NO_SCTP
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+ !(s->shutdown & SSL_SENT_SHUTDOWN))
+ {
+ ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
+ if (ret < 0) return -1;
+
+ if (ret == 0)
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, NULL);
+ }
+#endif
+ ret = ssl3_shutdown(s);
+#ifndef OPENSSL_NO_SCTP
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL);
+#endif
+ return ret;
+ }
+
+#ifndef OPENSSL_NO_HEARTBEATS
+int
+dtls1_process_heartbeat(SSL *s)
+ {
+ unsigned char *p = &s->s3->rrec.data[0], *pl;
+ unsigned short hbtype;
+ unsigned int payload;
+ unsigned int padding = 16; /* Use minimum padding */
+
+ /* Read type and payload length first */
+ hbtype = *p++;
+ n2s(p, payload);
+ pl = p;
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
+ &s->s3->rrec.data[0], s->s3->rrec.length,
+ s, s->msg_callback_arg);
+
+ if (hbtype == TLS1_HB_REQUEST)
+ {
+ unsigned char *buffer, *bp;
+ int r;
+
+ /* Allocate memory for the response, size is 1 byte
+ * message type, plus 2 bytes payload length, plus
+ * payload, plus padding
+ */
+ buffer = OPENSSL_malloc(1 + 2 + payload + padding);
+ bp = buffer;
+
+ /* Enter response type, length and copy payload */
+ *bp++ = TLS1_HB_RESPONSE;
+ s2n(payload, bp);
+ memcpy(bp, pl, payload);
+ bp += payload;
+ /* Random padding */
+ RAND_pseudo_bytes(bp, padding);
+
+ r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
+
+ if (r >= 0 && s->msg_callback)
+ s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
+ buffer, 3 + payload + padding,
+ s, s->msg_callback_arg);
+
+ OPENSSL_free(buffer);
+
+ if (r < 0)
+ return r;
+ }
+ else if (hbtype == TLS1_HB_RESPONSE)
+ {
+ unsigned int seq;
+
+ /* We only send sequence numbers (2 bytes unsigned int),
+ * and 16 random bytes, so we just try to read the
+ * sequence number */
+ n2s(pl, seq);
+
+ if (payload == 18 && seq == s->tlsext_hb_seq)
+ {
+ dtls1_stop_timer(s);
+ s->tlsext_hb_seq++;
+ s->tlsext_hb_pending = 0;
+ }
+ }
+
+ return 0;
+ }
+
+int
+dtls1_heartbeat(SSL *s)
+ {
+ unsigned char *buf, *p;
+ int ret;
+ unsigned int payload = 18; /* Sequence number + random bytes */
+ unsigned int padding = 16; /* Use minimum padding */
+
+ /* Only send if peer supports and accepts HB requests... */
+ if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
+ s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS)
+ {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
+ return -1;
+ }
+
+ /* ...and there is none in flight yet... */
+ if (s->tlsext_hb_pending)
+ {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING);
+ return -1;
+ }
+
+ /* ...and no handshake in progress. */
+ if (SSL_in_init(s) || s->in_handshake)
+ {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE);
+ return -1;
+ }
+
+ /* Check if padding is too long, payload and padding
+ * must not exceed 2^14 - 3 = 16381 bytes in total.
+ */
+ OPENSSL_assert(payload + padding <= 16381);
+
+ /* Create HeartBeat message, we just use a sequence number
+ * as payload to distuingish different messages and add
+ * some random stuff.
+ * - Message Type, 1 byte
+ * - Payload Length, 2 bytes (unsigned int)
+ * - Payload, the sequence number (2 bytes uint)
+ * - Payload, random bytes (16 bytes uint)
+ * - Padding
+ */
+ buf = OPENSSL_malloc(1 + 2 + payload + padding);
+ p = buf;
+ /* Message Type */
+ *p++ = TLS1_HB_REQUEST;
+ /* Payload length (18 bytes here) */
+ s2n(payload, p);
+ /* Sequence number */
+ s2n(s->tlsext_hb_seq, p);
+ /* 16 random bytes */
+ RAND_pseudo_bytes(p, 16);
+ p += 16;
+ /* Random padding */
+ RAND_pseudo_bytes(p, padding);
+
+ ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
+ if (ret >= 0)
+ {
+ if (s->msg_callback)
+ s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
+ buf, 3 + payload + padding,
+ s, s->msg_callback_arg);
+
+ dtls1_start_timer(s);
+ s->tlsext_hb_pending = 1;
+ }
+
+ OPENSSL_free(buf);
+
+ return ret;
+ }
+#endif
diff --git a/lib/libssl/src/ssl/d1_enc.c b/lib/libssl/src/ssl/d1_enc.c
index becbab91c21..07a5e97ce5c 100644
--- a/lib/libssl/src/ssl/d1_enc.c
+++ b/lib/libssl/src/ssl/d1_enc.c
@@ -260,7 +260,7 @@ int dtls1_enc(SSL *s, int send)
}
/* TLS 1.0 does not bound the number of padding bytes by the block size.
* All of them must have value 'padding_length'. */
- if (i > (int)rec->length)
+ if (i + bs > (int)rec->length)
{
/* Incorrect padding. SSLerr() and ssl3_alert are done
* by caller: we don't want to reveal whether this is
diff --git a/lib/libssl/src/ssl/d1_lib.c b/lib/libssl/src/ssl/d1_lib.c
index c3b77c889bd..f61f7181830 100644
--- a/lib/libssl/src/ssl/d1_lib.c
+++ b/lib/libssl/src/ssl/d1_lib.c
@@ -82,6 +82,7 @@ SSL3_ENC_METHOD DTLSv1_enc_data={
TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
tls1_alert_code,
+ tls1_export_keying_material,
};
long dtls1_default_timeout(void)
@@ -291,6 +292,15 @@ const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
void dtls1_start_timer(SSL *s)
{
+#ifndef OPENSSL_NO_SCTP
+ /* Disable timer for SCTP */
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+ {
+ memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
+ return;
+ }
+#endif
+
/* If timer is not set, initialize duration with 1 second */
if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
{
@@ -381,6 +391,7 @@ void dtls1_double_timeout(SSL *s)
void dtls1_stop_timer(SSL *s)
{
/* Reset everything */
+ memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
s->d1->timeout_duration = 1;
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
@@ -388,10 +399,28 @@ void dtls1_stop_timer(SSL *s)
dtls1_clear_record_buffer(s);
}
-int dtls1_handle_timeout(SSL *s)
+int dtls1_check_timeout_num(SSL *s)
{
- DTLS1_STATE *state;
+ s->d1->timeout.num_alerts++;
+
+ /* Reduce MTU after 2 unsuccessful retransmissions */
+ if (s->d1->timeout.num_alerts > 2)
+ {
+ s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
+ }
+ if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
+ {
+ /* fail the connection, enough alerts have been sent */
+ SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM,SSL_R_READ_TIMEOUT_EXPIRED);
+ return -1;
+ }
+
+ return 0;
+ }
+
+int dtls1_handle_timeout(SSL *s)
+ {
/* if no timer is expired, don't do anything */
if (!dtls1_is_timer_expired(s))
{
@@ -399,20 +428,23 @@ int dtls1_handle_timeout(SSL *s)
}
dtls1_double_timeout(s);
- state = s->d1;
- state->timeout.num_alerts++;
- if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
- {
- /* fail the connection, enough alerts have been sent */
- SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
+
+ if (dtls1_check_timeout_num(s) < 0)
return -1;
+
+ s->d1->timeout.read_timeouts++;
+ if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
+ {
+ s->d1->timeout.read_timeouts = 1;
}
- state->timeout.read_timeouts++;
- if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
+#ifndef OPENSSL_NO_HEARTBEATS
+ if (s->tlsext_hb_pending)
{
- state->timeout.read_timeouts = 1;
+ s->tlsext_hb_pending = 0;
+ return dtls1_heartbeat(s);
}
+#endif
dtls1_start_timer(s);
return dtls1_retransmit_buffered_messages(s);
diff --git a/lib/libssl/src/ssl/d1_srtp.c b/lib/libssl/src/ssl/d1_srtp.c
new file mode 100644
index 00000000000..928935bd8b4
--- /dev/null
+++ b/lib/libssl/src/ssl/d1_srtp.c
@@ -0,0 +1,493 @@
+/* ssl/t1_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/*
+ DTLS code by Eric Rescorla <ekr@rtfm.com>
+
+ Copyright (C) 2006, Network Resonance, Inc.
+ Copyright (C) 2011, RTFM, Inc.
+*/
+
+#ifndef OPENSSL_NO_SRTP
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+#include "srtp.h"
+
+
+static SRTP_PROTECTION_PROFILE srtp_known_profiles[]=
+ {
+ {
+ "SRTP_AES128_CM_SHA1_80",
+ SRTP_AES128_CM_SHA1_80,
+ },
+ {
+ "SRTP_AES128_CM_SHA1_32",
+ SRTP_AES128_CM_SHA1_32,
+ },
+#if 0
+ {
+ "SRTP_NULL_SHA1_80",
+ SRTP_NULL_SHA1_80,
+ },
+ {
+ "SRTP_NULL_SHA1_32",
+ SRTP_NULL_SHA1_32,
+ },
+#endif
+ {0}
+ };
+
+static int find_profile_by_name(char *profile_name,
+ SRTP_PROTECTION_PROFILE **pptr,unsigned len)
+ {
+ SRTP_PROTECTION_PROFILE *p;
+
+ p=srtp_known_profiles;
+ while(p->name)
+ {
+ if((len == strlen(p->name)) && !strncmp(p->name,profile_name,
+ len))
+ {
+ *pptr=p;
+ return 0;
+ }
+
+ p++;
+ }
+
+ return 1;
+ }
+
+static int find_profile_by_num(unsigned profile_num,
+ SRTP_PROTECTION_PROFILE **pptr)
+ {
+ SRTP_PROTECTION_PROFILE *p;
+
+ p=srtp_known_profiles;
+ while(p->name)
+ {
+ if(p->id == profile_num)
+ {
+ *pptr=p;
+ return 0;
+ }
+ p++;
+ }
+
+ return 1;
+ }
+
+static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out)
+ {
+ STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
+
+ char *col;
+ char *ptr=(char *)profiles_string;
+
+ SRTP_PROTECTION_PROFILE *p;
+
+ if(!(profiles=sk_SRTP_PROTECTION_PROFILE_new_null()))
+ {
+ SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
+ return 1;
+ }
+
+ do
+ {
+ col=strchr(ptr,':');
+
+ if(!find_profile_by_name(ptr,&p,
+ col ? col-ptr : (int)strlen(ptr)))
+ {
+ sk_SRTP_PROTECTION_PROFILE_push(profiles,p);
+ }
+ else
+ {
+ SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
+ return 1;
+ }
+
+ if(col) ptr=col+1;
+ } while (col);
+
+ *out=profiles;
+
+ return 0;
+ }
+
+int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,const char *profiles)
+ {
+ return ssl_ctx_make_profiles(profiles,&ctx->srtp_profiles);
+ }
+
+int SSL_set_tlsext_use_srtp(SSL *s,const char *profiles)
+ {
+ return ssl_ctx_make_profiles(profiles,&s->srtp_profiles);
+ }
+
+
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s)
+ {
+ if(s != NULL)
+ {
+ if(s->srtp_profiles != NULL)
+ {
+ return s->srtp_profiles;
+ }
+ else if((s->ctx != NULL) &&
+ (s->ctx->srtp_profiles != NULL))
+ {
+ return s->ctx->srtp_profiles;
+ }
+ }
+
+ return NULL;
+ }
+
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
+ {
+ return s->srtp_profile;
+ }
+
+/* Note: this function returns 0 length if there are no
+ profiles specified */
+int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
+ {
+ int ct=0;
+ int i;
+ STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0;
+ SRTP_PROTECTION_PROFILE *prof;
+
+ clnt=SSL_get_srtp_profiles(s);
+ ct=sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
+
+ if(p)
+ {
+ if(ct==0)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
+ return 1;
+ }
+
+ if((2 + ct*2 + 1) > maxlen)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+ return 1;
+ }
+
+ /* Add the length */
+ s2n(ct * 2, p);
+ for(i=0;i<ct;i++)
+ {
+ prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i);
+ s2n(prof->id,p);
+ }
+
+ /* Add an empty use_mki value */
+ *p++ = 0;
+ }
+
+ *len=2 + ct*2 + 1;
+
+ return 0;
+ }
+
+
+int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
+ {
+ SRTP_PROTECTION_PROFILE *cprof,*sprof;
+ STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0,*srvr;
+ int ct;
+ int mki_len;
+ int i,j;
+ int id;
+ int ret;
+
+ /* Length value + the MKI length */
+ if(len < 3)
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ /* Pull off the length of the cipher suite list */
+ n2s(d, ct);
+ len -= 2;
+
+ /* Check that it is even */
+ if(ct%2)
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ /* Check that lengths are consistent */
+ if(len < (ct + 1))
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+
+ clnt=sk_SRTP_PROTECTION_PROFILE_new_null();
+
+ while(ct)
+ {
+ n2s(d,id);
+ ct-=2;
+ len-=2;
+
+ if(!find_profile_by_num(id,&cprof))
+ {
+ sk_SRTP_PROTECTION_PROFILE_push(clnt,cprof);
+ }
+ else
+ {
+ ; /* Ignore */
+ }
+ }
+
+ /* Now extract the MKI value as a sanity check, but discard it for now */
+ mki_len = *d;
+ d++; len--;
+
+ if (mki_len != len)
+ {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_MKI_VALUE);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ srvr=SSL_get_srtp_profiles(s);
+
+ /* Pick our most preferred profile. If no profiles have been
+ configured then the outer loop doesn't run
+ (sk_SRTP_PROTECTION_PROFILE_num() = -1)
+ and so we just return without doing anything */
+ for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(srvr);i++)
+ {
+ sprof=sk_SRTP_PROTECTION_PROFILE_value(srvr,i);
+
+ for(j=0;j<sk_SRTP_PROTECTION_PROFILE_num(clnt);j++)
+ {
+ cprof=sk_SRTP_PROTECTION_PROFILE_value(clnt,j);
+
+ if(cprof->id==sprof->id)
+ {
+ s->srtp_profile=sprof;
+ *al=0;
+ ret=0;
+ goto done;
+ }
+ }
+ }
+
+ ret=0;
+
+done:
+ if(clnt) sk_SRTP_PROTECTION_PROFILE_free(clnt);
+
+ return ret;
+ }
+
+int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
+ {
+ if(p)
+ {
+ if(maxlen < 5)
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+ return 1;
+ }
+
+ if(s->srtp_profile==0)
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_USE_SRTP_NOT_NEGOTIATED);
+ return 1;
+ }
+ s2n(2, p);
+ s2n(s->srtp_profile->id,p);
+ *p++ = 0;
+ }
+ *len=5;
+
+ return 0;
+ }
+
+
+int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
+ {
+ unsigned id;
+ int i;
+ int ct;
+
+ STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
+ SRTP_PROTECTION_PROFILE *prof;
+
+ if(len!=5)
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ n2s(d, ct);
+ if(ct!=2)
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ n2s(d,id);
+ if (*d) /* Must be no MKI, since we never offer one */
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_MKI_VALUE);
+ *al=SSL_AD_ILLEGAL_PARAMETER;
+ return 1;
+ }
+
+ clnt=SSL_get_srtp_profiles(s);
+
+ /* Throw an error if the server gave us an unsolicited extension */
+ if (clnt == NULL)
+ {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_NO_SRTP_PROFILES);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ /* Check to see if the server gave us something we support
+ (and presumably offered)
+ */
+ for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(clnt);i++)
+ {
+ prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i);
+
+ if(prof->id == id)
+ {
+ s->srtp_profile=prof;
+ *al=0;
+ return 0;
+ }
+ }
+
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al=SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+
+#endif
diff --git a/lib/libssl/src/ssl/install-ssl.com b/lib/libssl/src/ssl/install-ssl.com
index 1bd6ccaa7ae..afe6967f853 100755
--- a/lib/libssl/src/ssl/install-ssl.com
+++ b/lib/libssl/src/ssl/install-ssl.com
@@ -73,7 +73,7 @@ $ if f$parse("wrk_sslxexe:") .eqs. "" then -
$ if f$parse("wrk_sslxlib:") .eqs. "" then -
create /directory /log wrk_sslxlib:
$!
-$ exheader := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h
+$ exheader := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h, srtp.h
$ e_exe := ssl_task
$ libs := ssl_libssl
$!
diff --git a/lib/libssl/src/ssl/srtp.h b/lib/libssl/src/ssl/srtp.h
new file mode 100644
index 00000000000..c0cf33ef288
--- /dev/null
+++ b/lib/libssl/src/ssl/srtp.h
@@ -0,0 +1,145 @@
+/* ssl/tls1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/*
+ DTLS code by Eric Rescorla <ekr@rtfm.com>
+
+ Copyright (C) 2006, Network Resonance, Inc.
+ Copyright (C) 2011, RTFM, Inc.
+*/
+
+#ifndef HEADER_D1_SRTP_H
+#define HEADER_D1_SRTP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define SRTP_AES128_CM_SHA1_80 0x0001
+#define SRTP_AES128_CM_SHA1_32 0x0002
+#define SRTP_AES128_F8_SHA1_80 0x0003
+#define SRTP_AES128_F8_SHA1_32 0x0004
+#define SRTP_NULL_SHA1_80 0x0005
+#define SRTP_NULL_SHA1_32 0x0006
+
+int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
+int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/libssl/src/ssl/tls_srp.c b/lib/libssl/src/ssl/tls_srp.c
new file mode 100644
index 00000000000..8512c4daf65
--- /dev/null
+++ b/lib/libssl/src/ssl/tls_srp.c
@@ -0,0 +1,506 @@
+/* ssl/tls_srp.c */
+/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
+ * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004-2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SRP
+
+#include <openssl/rand.h>
+#include <openssl/srp.h>
+#include <openssl/err.h>
+
+int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
+ {
+ if (ctx == NULL)
+ return 0;
+ OPENSSL_free(ctx->srp_ctx.login);
+ BN_free(ctx->srp_ctx.N);
+ BN_free(ctx->srp_ctx.g);
+ BN_free(ctx->srp_ctx.s);
+ BN_free(ctx->srp_ctx.B);
+ BN_free(ctx->srp_ctx.A);
+ BN_free(ctx->srp_ctx.a);
+ BN_free(ctx->srp_ctx.b);
+ BN_free(ctx->srp_ctx.v);
+ ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
+ ctx->srp_ctx.SRP_cb_arg = NULL;
+ ctx->srp_ctx.SRP_verify_param_callback = NULL;
+ ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+ ctx->srp_ctx.N = NULL;
+ ctx->srp_ctx.g = NULL;
+ ctx->srp_ctx.s = NULL;
+ ctx->srp_ctx.B = NULL;
+ ctx->srp_ctx.A = NULL;
+ ctx->srp_ctx.a = NULL;
+ ctx->srp_ctx.b = NULL;
+ ctx->srp_ctx.v = NULL;
+ ctx->srp_ctx.login = NULL;
+ ctx->srp_ctx.info = NULL;
+ ctx->srp_ctx.strength = SRP_MINIMAL_N;
+ ctx->srp_ctx.srp_Mask = 0;
+ return (1);
+ }
+
+int SSL_SRP_CTX_free(struct ssl_st *s)
+ {
+ if (s == NULL)
+ return 0;
+ OPENSSL_free(s->srp_ctx.login);
+ BN_free(s->srp_ctx.N);
+ BN_free(s->srp_ctx.g);
+ BN_free(s->srp_ctx.s);
+ BN_free(s->srp_ctx.B);
+ BN_free(s->srp_ctx.A);
+ BN_free(s->srp_ctx.a);
+ BN_free(s->srp_ctx.b);
+ BN_free(s->srp_ctx.v);
+ s->srp_ctx.TLS_ext_srp_username_callback = NULL;
+ s->srp_ctx.SRP_cb_arg = NULL;
+ s->srp_ctx.SRP_verify_param_callback = NULL;
+ s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+ s->srp_ctx.N = NULL;
+ s->srp_ctx.g = NULL;
+ s->srp_ctx.s = NULL;
+ s->srp_ctx.B = NULL;
+ s->srp_ctx.A = NULL;
+ s->srp_ctx.a = NULL;
+ s->srp_ctx.b = NULL;
+ s->srp_ctx.v = NULL;
+ s->srp_ctx.login = NULL;
+ s->srp_ctx.info = NULL;
+ s->srp_ctx.strength = SRP_MINIMAL_N;
+ s->srp_ctx.srp_Mask = 0;
+ return (1);
+ }
+
+int SSL_SRP_CTX_init(struct ssl_st *s)
+ {
+ SSL_CTX *ctx;
+
+ if ((s == NULL) || ((ctx = s->ctx) == NULL))
+ return 0;
+ s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
+ /* set client Hello login callback */
+ s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback;
+ /* set SRP N/g param callback for verification */
+ s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback;
+ /* set SRP client passwd callback */
+ s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
+
+ s->srp_ctx.N = NULL;
+ s->srp_ctx.g = NULL;
+ s->srp_ctx.s = NULL;
+ s->srp_ctx.B = NULL;
+ s->srp_ctx.A = NULL;
+ s->srp_ctx.a = NULL;
+ s->srp_ctx.b = NULL;
+ s->srp_ctx.v = NULL;
+ s->srp_ctx.login = NULL;
+ s->srp_ctx.info = ctx->srp_ctx.info;
+ s->srp_ctx.strength = ctx->srp_ctx.strength;
+
+ if (((ctx->srp_ctx.N != NULL) &&
+ ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) ||
+ ((ctx->srp_ctx.g != NULL) &&
+ ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) ||
+ ((ctx->srp_ctx.s != NULL) &&
+ ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) ||
+ ((ctx->srp_ctx.B != NULL) &&
+ ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) ||
+ ((ctx->srp_ctx.A != NULL) &&
+ ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) ||
+ ((ctx->srp_ctx.a != NULL) &&
+ ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) ||
+ ((ctx->srp_ctx.v != NULL) &&
+ ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) ||
+ ((ctx->srp_ctx.b != NULL) &&
+ ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL)))
+ {
+ SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_BN_LIB);
+ goto err;
+ }
+ if ((ctx->srp_ctx.login != NULL) &&
+ ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL))
+ {
+ SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
+
+ return (1);
+err:
+ OPENSSL_free(s->srp_ctx.login);
+ BN_free(s->srp_ctx.N);
+ BN_free(s->srp_ctx.g);
+ BN_free(s->srp_ctx.s);
+ BN_free(s->srp_ctx.B);
+ BN_free(s->srp_ctx.A);
+ BN_free(s->srp_ctx.a);
+ BN_free(s->srp_ctx.b);
+ BN_free(s->srp_ctx.v);
+ return (0);
+ }
+
+int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
+ {
+ if (ctx == NULL)
+ return 0;
+
+ ctx->srp_ctx.SRP_cb_arg = NULL;
+ /* set client Hello login callback */
+ ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
+ /* set SRP N/g param callback for verification */
+ ctx->srp_ctx.SRP_verify_param_callback = NULL;
+ /* set SRP client passwd callback */
+ ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+
+ ctx->srp_ctx.N = NULL;
+ ctx->srp_ctx.g = NULL;
+ ctx->srp_ctx.s = NULL;
+ ctx->srp_ctx.B = NULL;
+ ctx->srp_ctx.A = NULL;
+ ctx->srp_ctx.a = NULL;
+ ctx->srp_ctx.b = NULL;
+ ctx->srp_ctx.v = NULL;
+ ctx->srp_ctx.login = NULL;
+ ctx->srp_ctx.srp_Mask = 0;
+ ctx->srp_ctx.info = NULL;
+ ctx->srp_ctx.strength = SRP_MINIMAL_N;
+
+ return (1);
+ }
+
+/* server side */
+int SSL_srp_server_param_with_username(SSL *s, int *ad)
+ {
+ unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
+ int al;
+
+ *ad = SSL_AD_UNKNOWN_PSK_IDENTITY;
+ if ((s->srp_ctx.TLS_ext_srp_username_callback !=NULL) &&
+ ((al = s->srp_ctx.TLS_ext_srp_username_callback(s, ad, s->srp_ctx.SRP_cb_arg))!=SSL_ERROR_NONE))
+ return al;
+
+ *ad = SSL_AD_INTERNAL_ERROR;
+ if ((s->srp_ctx.N == NULL) ||
+ (s->srp_ctx.g == NULL) ||
+ (s->srp_ctx.s == NULL) ||
+ (s->srp_ctx.v == NULL))
+ return SSL3_AL_FATAL;
+
+ RAND_bytes(b, sizeof(b));
+ s->srp_ctx.b = BN_bin2bn(b,sizeof(b),NULL);
+ OPENSSL_cleanse(b,sizeof(b));
+
+ /* Calculate: B = (kv + g^b) % N */
+
+ return ((s->srp_ctx.B = SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, s->srp_ctx.v)) != NULL)?
+ SSL_ERROR_NONE:SSL3_AL_FATAL;
+ }
+
+/* If the server just has the raw password, make up a verifier entry on the fly */
+int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp)
+ {
+ SRP_gN *GN = SRP_get_default_gN(grp);
+ if(GN == NULL) return -1;
+ s->srp_ctx.N = BN_dup(GN->N);
+ s->srp_ctx.g = BN_dup(GN->g);
+ if(s->srp_ctx.v != NULL)
+ {
+ BN_clear_free(s->srp_ctx.v);
+ s->srp_ctx.v = NULL;
+ }
+ if(s->srp_ctx.s != NULL)
+ {
+ BN_clear_free(s->srp_ctx.s);
+ s->srp_ctx.s = NULL;
+ }
+ if(!SRP_create_verifier_BN(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) return -1;
+
+ return 1;
+ }
+
+int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
+ BIGNUM *sa, BIGNUM *v, char *info)
+ {
+ if (N!= NULL)
+ {
+ if (s->srp_ctx.N != NULL)
+ {
+ if (!BN_copy(s->srp_ctx.N,N))
+ {
+ BN_free(s->srp_ctx.N);
+ s->srp_ctx.N = NULL;
+ }
+ }
+ else
+ s->srp_ctx.N = BN_dup(N);
+ }
+ if (g!= NULL)
+ {
+ if (s->srp_ctx.g != NULL)
+ {
+ if (!BN_copy(s->srp_ctx.g,g))
+ {
+ BN_free(s->srp_ctx.g);
+ s->srp_ctx.g = NULL;
+ }
+ }
+ else
+ s->srp_ctx.g = BN_dup(g);
+ }
+ if (sa!= NULL)
+ {
+ if (s->srp_ctx.s != NULL)
+ {
+ if (!BN_copy(s->srp_ctx.s,sa))
+ {
+ BN_free(s->srp_ctx.s);
+ s->srp_ctx.s = NULL;
+ }
+ }
+ else
+ s->srp_ctx.s = BN_dup(sa);
+ }
+ if (v!= NULL)
+ {
+ if (s->srp_ctx.v != NULL)
+ {
+ if (!BN_copy(s->srp_ctx.v,v))
+ {
+ BN_free(s->srp_ctx.v);
+ s->srp_ctx.v = NULL;
+ }
+ }
+ else
+ s->srp_ctx.v = BN_dup(v);
+ }
+ s->srp_ctx.info = info;
+
+ if (!(s->srp_ctx.N) ||
+ !(s->srp_ctx.g) ||
+ !(s->srp_ctx.s) ||
+ !(s->srp_ctx.v))
+ return -1;
+
+ return 1;
+ }
+
+int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key)
+ {
+ BIGNUM *K = NULL, *u = NULL;
+ int ret = -1, tmp_len;
+ unsigned char *tmp = NULL;
+
+ if (!SRP_Verify_A_mod_N(s->srp_ctx.A,s->srp_ctx.N))
+ goto err;
+ if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N)))
+ goto err;
+ if (!(K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N)))
+ goto err;
+
+ tmp_len = BN_num_bytes(K);
+ if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
+ goto err;
+ BN_bn2bin(K, tmp);
+ ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
+err:
+ if (tmp)
+ {
+ OPENSSL_cleanse(tmp,tmp_len) ;
+ OPENSSL_free(tmp);
+ }
+ BN_clear_free(K);
+ BN_clear_free(u);
+ return ret;
+ }
+
+/* client side */
+int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key)
+ {
+ BIGNUM *x = NULL, *u = NULL, *K = NULL;
+ int ret = -1, tmp_len;
+ char *passwd = NULL;
+ unsigned char *tmp = NULL;
+
+ /* Checks if b % n == 0
+ */
+ if (SRP_Verify_B_mod_N(s->srp_ctx.B,s->srp_ctx.N)==0) goto err;
+ if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N))) goto err;
+ if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) goto err;
+ if (!(passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg))) goto err;
+ if (!(x = SRP_Calc_x(s->srp_ctx.s,s->srp_ctx.login,passwd))) goto err;
+ if (!(K = SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, s->srp_ctx.a, u))) goto err;
+
+ tmp_len = BN_num_bytes(K);
+ if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) goto err;
+ BN_bn2bin(K, tmp);
+ ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
+err:
+ if (tmp)
+ {
+ OPENSSL_cleanse(tmp,tmp_len) ;
+ OPENSSL_free(tmp);
+ }
+ BN_clear_free(K);
+ BN_clear_free(x);
+ if (passwd)
+ {
+ OPENSSL_cleanse(passwd,strlen(passwd)) ;
+ OPENSSL_free(passwd);
+ }
+ BN_clear_free(u);
+ return ret;
+ }
+
+int SRP_Calc_A_param(SSL *s)
+ {
+ unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
+
+ if (BN_num_bits(s->srp_ctx.N) < s->srp_ctx.strength)
+ return -1;
+
+ if (s->srp_ctx.SRP_verify_param_callback ==NULL &&
+ !SRP_check_known_gN_param(s->srp_ctx.g,s->srp_ctx.N))
+ return -1 ;
+
+ RAND_bytes(rnd, sizeof(rnd));
+ s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
+ OPENSSL_cleanse(rnd, sizeof(rnd));
+
+ if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a,s->srp_ctx.N,s->srp_ctx.g)))
+ return -1;
+
+ /* We can have a callback to verify SRP param!! */
+ if (s->srp_ctx.SRP_verify_param_callback !=NULL)
+ return s->srp_ctx.SRP_verify_param_callback(s,s->srp_ctx.SRP_cb_arg);
+
+ return 1;
+ }
+
+BIGNUM *SSL_get_srp_g(SSL *s)
+ {
+ if (s->srp_ctx.g != NULL)
+ return s->srp_ctx.g;
+ return s->ctx->srp_ctx.g;
+ }
+
+BIGNUM *SSL_get_srp_N(SSL *s)
+ {
+ if (s->srp_ctx.N != NULL)
+ return s->srp_ctx.N;
+ return s->ctx->srp_ctx.N;
+ }
+
+char *SSL_get_srp_username(SSL *s)
+ {
+ if (s->srp_ctx.login != NULL)
+ return s->srp_ctx.login;
+ return s->ctx->srp_ctx.login;
+ }
+
+char *SSL_get_srp_userinfo(SSL *s)
+ {
+ if (s->srp_ctx.info != NULL)
+ return s->srp_ctx.info;
+ return s->ctx->srp_ctx.info;
+ }
+
+#define tls1_ctx_ctrl ssl3_ctx_ctrl
+#define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
+
+int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name)
+ {
+ return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME,0,name);
+ }
+
+int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password)
+ {
+ return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD,0,password);
+ }
+
+int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
+ {
+ return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
+ NULL);
+ }
+
+int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, int (*cb)(SSL *,void *))
+ {
+ return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
+ (void (*)(void))cb);
+ }
+
+int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
+ {
+ return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_SRP_ARG,0,arg);
+ }
+
+int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
+ int (*cb)(SSL *,int *,void *))
+ {
+ return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
+ (void (*)(void))cb);
+ }
+
+int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *))
+ {
+ return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
+ (void (*)(void))cb);
+ }
+
+#endif