static int ssl23_client_hello(SSL *s) { unsigned char *buf; unsigned char *p,*d; int i,ch_len; unsigned long l; int ssl2_compat; int version = 0, version_major, version_minor; #ifndef OPENSSL_NO_COMP int j; SSL_COMP *comp; #endif int ret; unsigned long mask, options = s->options; ssl2_compat = (options & SSL_OP_NO_SSLv2) ? 0 : 1; if (ssl2_compat && ssl23_no_ssl2_ciphers(s)) ssl2_compat = 0; /* * SSL_OP_NO_X disables all protocols above X *if* there are * some protocols below X enabled. This is required in order * to maintain "version capability" vector contiguous. So * that if application wants to disable TLS1.0 in favour of * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. */ mask = SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1 #if !defined(OPENSSL_NO_SSL3) |SSL_OP_NO_SSLv3 #endif #if !defined(OPENSSL_NO_SSL2) |(ssl2_compat?SSL_OP_NO_SSLv2:0) #endif ; #if !defined(OPENSSL_NO_TLS1_2_CLIENT) version = TLS1_2_VERSION; if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask) version = TLS1_1_VERSION; #else version = TLS1_1_VERSION; #endif mask &= ~SSL_OP_NO_TLSv1_1; if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) version = TLS1_VERSION; mask &= ~SSL_OP_NO_TLSv1; #if !defined(OPENSSL_NO_SSL3) if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) version = SSL3_VERSION; mask &= ~SSL_OP_NO_SSLv3; #endif #if !defined(OPENSSL_NO_SSL2) if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask) version = SSL2_VERSION; #endif #ifndef OPENSSL_NO_TLSEXT if (version != SSL2_VERSION) { /* have to disable SSL 2.0 compatibility if we need TLS extensions */ if (s->tlsext_hostname != NULL) ssl2_compat = 0; if (s->tlsext_status_type != -1) ssl2_compat = 0; #ifdef TLSEXT_TYPE_opaque_prf_input if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL) ssl2_compat = 0; #endif } #endif buf=(unsigned char *)s->init_buf->data; if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { #if 0 /* don't reuse session-id's */ if (!ssl_get_new_session(s,0)) { return(-1); } #endif p=s->s3->client_random; if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0) return -1; if (version == TLS1_2_VERSION) { version_major = TLS1_2_VERSION_MAJOR; version_minor = TLS1_2_VERSION_MINOR; } else if (version == TLS1_1_VERSION) { version_major = TLS1_1_VERSION_MAJOR; version_minor = TLS1_1_VERSION_MINOR; } else if (version == TLS1_VERSION) { version_major = TLS1_VERSION_MAJOR; version_minor = TLS1_VERSION_MINOR; } #ifdef OPENSSL_FIPS else if(FIPS_mode()) { SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); return -1; } #endif else if (version == SSL3_VERSION) { version_major = SSL3_VERSION_MAJOR; version_minor = SSL3_VERSION_MINOR; } else if (version == SSL2_VERSION) { version_major = SSL2_VERSION_MAJOR; version_minor = SSL2_VERSION_MINOR; } else { SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_PROTOCOLS_AVAILABLE); return(-1); } s->client_version = version; if (ssl2_compat) { /* create SSL 2.0 compatible Client Hello */ /* two byte record header will be written last */ d = &(buf[2]); p = d + 9; /* leave space for message type, version, individual length fields */ *(d++) = SSL2_MT_CLIENT_HELLO; *(d++) = version_major; *(d++) = version_minor; /* Ciphers supported */ i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),p,0); if (i == 0) { /* no ciphers */ SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); return -1; } s2n(i,d); p+=i; /* put in the session-id length (zero since there is no reuse) */ #if 0 s->session->session_id_length=0; #endif s2n(0,d); if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) ch_len=SSL2_CHALLENGE_LENGTH; else ch_len=SSL2_MAX_CHALLENGE_LENGTH; /* write out sslv2 challenge */ /* Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it is one of SSL2_MAX_CHALLENGE_LENGTH (32) or SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for futurproofing */ if (SSL3_RANDOM_SIZE < ch_len) i=SSL3_RANDOM_SIZE; else i=ch_len; s2n(i,d); memset(&(s->s3->client_random[0]),0,SSL3_RANDOM_SIZE); if (RAND_pseudo_bytes(&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i) <= 0) return -1; memcpy(p,&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i); p+=i; i= p- &(buf[2]); buf[0]=((i>>8)&0xff)|0x80; buf[1]=(i&0xff); /* number of bytes to write */ s->init_num=i+2; s->init_off=0; ssl3_finish_mac(s,&(buf[2]),i); } else { /* create Client Hello in SSL 3.0/TLS 1.0 format */ /* do the record header (5 bytes) and handshake message * header (4 bytes) last. Note: the code to add the * padding extension in t1_lib.c depends on the size of * this prefix. */ d = p = &(buf[9]); *(p++) = version_major; *(p++) = version_minor; /* Random stuff */ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); p += SSL3_RANDOM_SIZE; /* Session ID (zero since there is no reuse) */ *(p++) = 0; /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),ssl3_put_cipher_by_char); if (i == 0) { SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); return -1; } #ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH /* Some servers hang if client hello > 256 bytes * as hack workaround chop number of supported ciphers * to keep it well below this if we use TLS v1.2 */ if (TLS1_get_version(s) >= TLS1_2_VERSION && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; #endif s2n(i,p); p+=i; /* COMPRESSION */ #ifdef OPENSSL_NO_COMP *(p++)=1; #else if ((s->options & SSL_OP_NO_COMPRESSION) || !s->ctx->comp_methods) j=0; else j=sk_SSL_COMP_num(s->ctx->comp_methods); *(p++)=1+j; for (i=0; i<j; i++) { comp=sk_SSL_COMP_value(s->ctx->comp_methods,i); *(p++)=comp->id; } #endif *(p++)=0; /* Add the NULL method */ #ifndef OPENSSL_NO_TLSEXT /* TLS extensions*/ if (ssl_prepare_clienthello_tlsext(s) <= 0) { SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); return -1; } if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) { SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); return -1; } #endif l = p-d; /* fill in 4-byte handshake header */ d=&(buf[5]); *(d++)=SSL3_MT_CLIENT_HELLO; l2n3(l,d); l += 4; if (l > SSL3_RT_MAX_PLAIN_LENGTH) { SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); return -1; } /* fill in 5-byte record header */ d=buf; *(d++) = SSL3_RT_HANDSHAKE; *(d++) = version_major; /* Some servers hang if we use long client hellos * and a record number > TLS 1.0. */ if (TLS1_get_client_version(s) > TLS1_VERSION) *(d++) = 1; else *(d++) = version_minor; s2n((int)l,d); /* number of bytes to write */ s->init_num=p-buf; s->init_off=0; ssl3_finish_mac(s,&(buf[5]), s->init_num - 5); } s->state=SSL23_ST_CW_CLNT_HELLO_B; s->init_off=0; }
/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. * * Returns: * 0: (in non-constant time) if the record is publically invalid (i.e. too * short etc). * 1: if the record's padding is valid / the encryption was successful. * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, * an internal error occured. */ int tls1_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; int bs,i,j,k,pad=0,ret,mac_size=0; const EVP_CIPHER *enc; if (send) { if (EVP_MD_CTX_md(s->write_hash)) { int n=EVP_MD_CTX_size(s->write_hash); OPENSSL_assert(n >= 0); } ds=s->enc_write_ctx; rec= &(s->s3->wrec); if (s->enc_write_ctx == NULL) enc=NULL; else { int ivlen; enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx); /* For TLSv1.1 and later explicit IV */ if (s->version >= TLS1_1_VERSION && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) ivlen = EVP_CIPHER_iv_length(enc); else ivlen = 0; if (ivlen > 1) { if ( rec->data != rec->input) /* we can't write into the input stream: * Can this ever happen?? (steve) */ fprintf(stderr, "%s:%d: rec->data != rec->input\n", __FILE__, __LINE__); else if (RAND_bytes(rec->input, ivlen) <= 0) return -1; } } } else { if (EVP_MD_CTX_md(s->read_hash)) { int n=EVP_MD_CTX_size(s->read_hash); OPENSSL_assert(n >= 0); } ds=s->enc_read_ctx; rec= &(s->s3->rrec); if (s->enc_read_ctx == NULL) enc=NULL; else enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx); } #ifdef KSSL_DEBUG printf("tls1_enc(%d)\n", send); #endif /* KSSL_DEBUG */ if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { memmove(rec->data,rec->input,rec->length); rec->input=rec->data; ret = 1; } else { l=rec->length; bs=EVP_CIPHER_block_size(ds->cipher); if (EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER) { unsigned char buf[13],*seq; seq = send?s->s3->write_sequence:s->s3->read_sequence; if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { unsigned char dtlsseq[9],*p=dtlsseq; s2n(send?s->d1->w_epoch:s->d1->r_epoch,p); memcpy(p,&seq[2],6); memcpy(buf,dtlsseq,8); } else { memcpy(buf,seq,8); for (i=7; i>=0; i--) /* increment */ { ++seq[i]; if (seq[i] != 0) break; } } buf[8]=rec->type; buf[9]=(unsigned char)(s->version>>8); buf[10]=(unsigned char)(s->version); buf[11]=rec->length>>8; buf[12]=rec->length&0xff; pad=EVP_CIPHER_CTX_ctrl(ds,EVP_CTRL_AEAD_TLS1_AAD,13,buf); if (send) { l+=pad; rec->length+=pad; } } else if ((bs != 1) && send)
int dtls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length) { unsigned char *pl; unsigned short hbtype; unsigned int payload; unsigned int padding = 16; /* Use minimum padding */ if (s->msg_callback) s->msg_callback(0, s->version, DTLS1_RT_HEARTBEAT, p, length, s, s->msg_callback_arg); /* Read type and payload length */ if (HEARTBEAT_SIZE_STD(0) > length) return 0; /* silently discard */ if (length > SSL3_RT_MAX_PLAIN_LENGTH) return 0; /* silently discard per RFC 6520 sec. 4 */ hbtype = *p++; n2s(p, payload); if (HEARTBEAT_SIZE_STD(payload) > length) return 0; /* silently discard per RFC 6520 sec. 4 */ pl = p; if (hbtype == TLS1_HB_REQUEST) { unsigned char *buffer, *bp; unsigned int write_length = HEARTBEAT_SIZE(payload, padding); int r; if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) return 0; /* Allocate memory for the response. */ buffer = OPENSSL_malloc(write_length); if (buffer == NULL) return -1; bp = buffer; /* Enter response type, length and copy payload */ *bp++ = TLS1_HB_RESPONSE; s2n(payload, bp); memcpy(bp, pl, payload); bp += payload; /* Random padding */ if (RAND_bytes(bp, padding) <= 0) { OPENSSL_free(buffer); return -1; } r = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buffer, write_length); if (r >= 0 && s->msg_callback) s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT, buffer, write_length, 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 = -1; unsigned int payload = 18; /* Sequence number + random bytes */ unsigned int padding = 16; /* Use minimum padding */ unsigned int size; /* Only send if peer supports and accepts HB requests... */ if (!(s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED) || s->tlsext_heartbeat & SSL_DTLSEXT_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) || ossl_statem_get_in_handshake(s)) { SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); return -1; } /*- * Create HeartBeat message, we just use a sequence number * as payload to distinguish different messages and add * some random stuff. */ size = HEARTBEAT_SIZE(payload, padding); buf = OPENSSL_malloc(size); if (buf == NULL) { SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_MALLOC_FAILURE); return -1; } 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 */ if (RAND_bytes(p, 16) <= 0) { SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); goto err; } p += 16; /* Random padding */ if (RAND_bytes(p, padding) <= 0) { SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); goto err; } ret = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buf, size); if (ret >= 0) { if (s->msg_callback) s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT, buf, size, s, s->msg_callback_arg); dtls1_start_timer(s); s->tlsext_hb_pending = 1; } err: OPENSSL_free(buf); return ret; }
int f_char(oprtype *a, opctype op) { triple *root, *last, *curr; oprtype argv[CHARMAXARGS], *argp; mval v; bool all_lits; char *c; int argc, i; error_def(ERR_FCHARMAXARGS); all_lits = TRUE; argp = &argv[0]; argc = 0; for (;;) { if (!intexpr(argp)) return FALSE; assert(argp->oprclass == TRIP_REF); if (argp->oprval.tref->opcode != OC_ILIT) all_lits = FALSE; argc++; argp++; if (window_token != TK_COMMA) break; advancewindow(); if (argc >= CHARMAXARGS) { stx_error(ERR_FCHARMAXARGS); return FALSE; } } if (all_lits) { if (stringpool.top - stringpool.free < argc) stp_gcol(argc); v.mvtype = MV_STR; v.str.addr = c = (char *) stringpool.free; argp = &argv[0]; for (; argc > 0 ;argc--, argp++) { i = argp->oprval.tref->operand[0].oprval.ilit; if ((i >= 0) && (i < 256)) /* only true for single byte character set */ *c++ = i; } v.str.len = c - v.str.addr; stringpool.free =(unsigned char *) c; s2n(&v); *a = put_lit(&v); return TRUE; } root = maketriple(op); root->operand[0] = put_ilit(argc + 2); curr = newtriple(OC_PARAMETER); curr->operand[0] = put_ilit(0); root->operand[1] = put_tref(curr); last = curr; argp = &argv[0]; for (; argc > 0 ;argc--, argp++) { curr = newtriple(OC_PARAMETER); curr->operand[0] = *argp; last->operand[1] = put_tref(curr); last = curr; } ins_triple(root); *a = put_tref(root); return TRUE; }
static int ssl23_client_hello(SSL *s) { unsigned char *buf; unsigned char *p, *d; int i; unsigned long l; int version = 0, version_major, version_minor; #ifndef OPENSSL_NO_COMP int j; SSL_COMP *comp; #endif int ret; unsigned long mask, options = s->options; /* * SSL_OP_NO_X disables all protocols above X *if* there are * some protocols below X enabled. This is required in order * to maintain "version capability" vector contiguous. So * that if application wants to disable TLS1.0 in favour of * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. */ mask = SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3; #if !defined(OPENSSL_NO_TLS1_2_CLIENT) version = TLS1_2_VERSION; if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask) version = TLS1_1_VERSION; #else version = TLS1_1_VERSION; #endif mask &= ~SSL_OP_NO_TLSv1_1; if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) version = TLS1_VERSION; mask &= ~SSL_OP_NO_TLSv1; if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) version = SSL3_VERSION; mask &= ~SSL_OP_NO_SSLv3; buf = (unsigned char *)s->init_buf->data; if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { #if 0 /* don't reuse session-id's */ if (!ssl_get_new_session(s, 0)) { return (-1); } #endif p = s->s3->client_random; if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0) return -1; if (version == TLS1_2_VERSION) { version_major = TLS1_2_VERSION_MAJOR; version_minor = TLS1_2_VERSION_MINOR; } else if (version == TLS1_1_VERSION) { version_major = TLS1_1_VERSION_MAJOR; version_minor = TLS1_1_VERSION_MINOR; } else if (version == TLS1_VERSION) { version_major = TLS1_VERSION_MAJOR; version_minor = TLS1_VERSION_MINOR; } else if (version == SSL3_VERSION) { version_major = SSL3_VERSION_MAJOR; version_minor = SSL3_VERSION_MINOR; } else { SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_PROTOCOLS_AVAILABLE); return (-1); } s->client_version = version; /* create Client Hello in SSL 3.0/TLS 1.0 format */ /* * Do the record header (5 bytes) and handshake * message header (4 bytes) last */ d = p = &(buf[9]); *(p++) = version_major; *(p++) = version_minor; /* Random stuff */ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); p += SSL3_RANDOM_SIZE; /* Session ID (zero since there is no reuse) */ *(p++) = 0; /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), ssl3_put_cipher_by_char); if (i == 0) { SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); return -1; } #ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH /* * Some servers hang if client hello > 256 bytes * as hack workaround chop number of supported ciphers * to keep it well below this if we use TLS v1.2 */ if (TLS1_get_version(s) >= TLS1_2_VERSION && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; #endif s2n(i, p); p += i; /* COMPRESSION */ #ifdef OPENSSL_NO_COMP *(p++) = 1; #else if ((s->options & SSL_OP_NO_COMPRESSION) || !s->ctx->comp_methods) j = 0; else j = sk_SSL_COMP_num(s->ctx->comp_methods); *(p++) = 1 + j; for (i = 0; i < j; i++) { comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); *(p++) = comp->id; } #endif /* Add the NULL method */ *(p++) = 0; #ifndef OPENSSL_NO_TLSEXT /* TLS extensions*/ if (ssl_prepare_clienthello_tlsext(s) <= 0) { SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); return -1; } if ((p = ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) { SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); return -1; } #endif l = p - d; /* fill in 4-byte handshake header */ d = &(buf[5]); *(d++) = SSL3_MT_CLIENT_HELLO; l2n3(l, d); l += 4; if (l > SSL3_RT_MAX_PLAIN_LENGTH) { SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); return -1; } /* fill in 5-byte record header */ d = buf; *(d++) = SSL3_RT_HANDSHAKE; *(d++) = version_major; /* * Some servers hang if we use long client hellos * and a record number > TLS 1.0. */ if (TLS1_get_client_version(s) > TLS1_VERSION) *(d++) = 1; else *(d++) = version_minor; s2n((int)l, d); /* number of bytes to write */ s->init_num = p - buf; s->init_off = 0; ssl3_finish_mac(s, &(buf[5]), s->init_num - 5); s->state = SSL23_ST_CW_CLNT_HELLO_B; s->init_off = 0; } /* SSL3_ST_CW_CLNT_HELLO_B */ ret = ssl23_write_bytes(s); if ((ret >= 2) && s->msg_callback) { /* Client Hello has been sent; tell msg_callback */ s->msg_callback(1, version, SSL3_RT_HANDSHAKE, s->init_buf->data + 5, ret - 5, s, s->msg_callback_arg); } return ret; }
int dtls1_client_hello(SSL *s) { unsigned char *buf; unsigned char *p, *d; unsigned int i; unsigned long l; buf = (unsigned char *)s->init_buf->data; if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { SSL_SESSION *sess = s->session; if ((s->session == NULL) || (s->session->ssl_version != s->version) || (!sess->session_id_length && !sess->tlsext_tick) || (s->session->not_resumable)) { if (!ssl_get_new_session(s, 0)) goto err; } /* else use the pre-loaded session */ p = s->s3->client_random; /* if client_random is initialized, reuse it, we are * required to use same upon reply to HelloVerify */ for (i = 0; p[i]=='\0' && i < sizeof(s->s3->client_random); i++) ; if (i == sizeof(s->s3->client_random)) arc4random_buf(p, sizeof(s->s3->client_random)); /* Do the message type and length last */ d = p = &(buf[DTLS1_HM_HEADER_LENGTH]); *(p++) = s->version >> 8; *(p++) = s->version&0xff; s->client_version = s->version; /* Random stuff */ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); p += SSL3_RANDOM_SIZE; /* Session ID */ if (s->new_session) i = 0; else i = s->session->session_id_length; *(p++) = i; if (i != 0) { if (i > sizeof s->session->session_id) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } memcpy(p, s->session->session_id, i); p += i; } /* cookie stuff */ if (s->d1->cookie_len > sizeof(s->d1->cookie)) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } *(p++) = s->d1->cookie_len; memcpy(p, s->d1->cookie, s->d1->cookie_len); p += s->d1->cookie_len; /* Ciphers supported */ i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]); if (i == 0) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); goto err; } s2n(i, p); p += i; /* add in (no) COMPRESSION */ *(p++) = 1; *(p++) = 0; /* Add the NULL method */ if ((p = ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } l = (p - d); d = buf; d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l); s->state = SSL3_ST_CW_CLNT_HELLO_B; /* number of bytes to write */ s->init_num = p - buf; s->init_off = 0; /* buffer the message to handle re-xmits */ dtls1_buffer_message(s, 0); }
static int ssl23_client_hello(SSL *s) { unsigned char *buf; unsigned char *p,*d; int i,j,ch_len; unsigned long Time,l; int ssl2_compat; int version = 0, version_major, version_minor; SSL_COMP *comp; int ret; ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1; if (!(s->options & SSL_OP_NO_TLSv1)) { version = TLS1_VERSION; } else if (!(s->options & SSL_OP_NO_SSLv3)) { version = SSL3_VERSION; } else if (!(s->options & SSL_OP_NO_SSLv2)) { version = SSL2_VERSION; } #ifndef OPENSSL_NO_TLSEXT if (version != SSL2_VERSION) { /* have to disable SSL 2.0 compatibility if we need TLS extensions */ if (s->tlsext_hostname != NULL) ssl2_compat = 0; } #endif buf=(unsigned char *)s->init_buf->data; if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { #if 0 /* don't reuse session-id's */ if (!ssl_get_new_session(s,0)) { return(-1); } #endif p=s->s3->client_random; Time=(unsigned long)time(NULL); /* Time */ l2n(Time,p); if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) return -1; if (version == TLS1_VERSION) { version_major = TLS1_VERSION_MAJOR; version_minor = TLS1_VERSION_MINOR; } else if (version == SSL3_VERSION) { version_major = SSL3_VERSION_MAJOR; version_minor = SSL3_VERSION_MINOR; } else if (version == SSL2_VERSION) { version_major = SSL2_VERSION_MAJOR; version_minor = SSL2_VERSION_MINOR; } else { SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_PROTOCOLS_AVAILABLE); return(-1); } s->client_version = version; if (ssl2_compat) { /* create SSL 2.0 compatible Client Hello */ /* two byte record header will be written last */ d = &(buf[2]); p = d + 9; /* leave space for message type, version, individual length fields */ *(d++) = SSL2_MT_CLIENT_HELLO; *(d++) = version_major; *(d++) = version_minor; /* Ciphers supported */ i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),p,0); if (i == 0) { /* no ciphers */ SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); return -1; } s2n(i,d); p+=i; /* put in the session-id length (zero since there is no reuse) */ #if 0 s->session->session_id_length=0; #endif s2n(0,d); if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) ch_len=SSL2_CHALLENGE_LENGTH; else ch_len=SSL2_MAX_CHALLENGE_LENGTH; /* write out sslv2 challenge */ if (SSL3_RANDOM_SIZE < ch_len) i=SSL3_RANDOM_SIZE; else i=ch_len; s2n(i,d); memset(&(s->s3->client_random[0]),0,SSL3_RANDOM_SIZE); if (RAND_pseudo_bytes(&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i) <= 0) return -1; memcpy(p,&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i); p+=i; i= p- &(buf[2]); buf[0]=((i>>8)&0xff)|0x80; buf[1]=(i&0xff); /* number of bytes to write */ s->init_num=i+2; s->init_off=0; ssl3_finish_mac(s,&(buf[2]),i); } else { /* create Client Hello in SSL 3.0/TLS 1.0 format */ /* do the record header (5 bytes) and handshake message header (4 bytes) last */ d = p = &(buf[9]); *(p++) = version_major; *(p++) = version_minor; /* Random stuff */ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); p += SSL3_RANDOM_SIZE; /* Session ID (zero since there is no reuse) */ *(p++) = 0; /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),ssl3_put_cipher_by_char); if (i == 0) { SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); return -1; } s2n(i,p); p+=i; /* COMPRESSION */ if (s->ctx->comp_methods == NULL) j=0; else j=sk_SSL_COMP_num(s->ctx->comp_methods); *(p++)=1+j; for (i=0; i<j; i++) { comp=sk_SSL_COMP_value(s->ctx->comp_methods,i); *(p++)=comp->id; } *(p++)=0; /* Add the NULL method */ #ifndef OPENSSL_NO_TLSEXT if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) { SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); return -1; } #endif l = p-d; *p = 42; /* fill in 4-byte handshake header */ d=&(buf[5]); *(d++)=SSL3_MT_CLIENT_HELLO; l2n3(l,d); l += 4; if (l > SSL3_RT_MAX_PLAIN_LENGTH) { SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); return -1; } /* fill in 5-byte record header */ d=buf; *(d++) = SSL3_RT_HANDSHAKE; *(d++) = version_major; *(d++) = version_minor; /* arguably we should send the *lowest* suported version here * (indicating, e.g., TLS 1.0 in "SSL 3.0 format") */ s2n((int)l,d); /* number of bytes to write */ s->init_num=p-buf; s->init_off=0; ssl3_finish_mac(s,&(buf[5]), s->init_num - 5); } s->state=SSL23_ST_CW_CLNT_HELLO_B; s->init_off=0; }
int tls1_mac(SSL *ssl, unsigned char *md, int send) { SSL3_RECORD *rec; unsigned char *mac_sec,*seq; const EVP_MD *hash; unsigned int md_size; int i; HMAC_CTX hmac; unsigned char buf[5]; if (send) { rec= &(ssl->s3->wrec); mac_sec= &(ssl->s3->write_mac_secret[0]); seq= &(ssl->s3->write_sequence[0]); hash=ssl->write_hash; } else { rec= &(ssl->s3->rrec); mac_sec= &(ssl->s3->read_mac_secret[0]); seq= &(ssl->s3->read_sequence[0]); hash=ssl->read_hash; } md_size=EVP_MD_size(hash); buf[0]=rec->type; if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER) { buf[1]=TLS1_VERSION_MAJOR; buf[2]=TLS1_VERSION_MINOR; } else { buf[1]=(unsigned char)(ssl->version>>8); buf[2]=(unsigned char)(ssl->version); } buf[3]=rec->length>>8; buf[4]=rec->length&0xff; /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ HMAC_CTX_init(&hmac); HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL); if (ssl->version == DTLS1_BAD_VER || (ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER)) { unsigned char dtlsseq[8],*p=dtlsseq; s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); memcpy (p,&seq[2],6); HMAC_Update(&hmac,dtlsseq,8); } else HMAC_Update(&hmac,seq,8); HMAC_Update(&hmac,buf,5); HMAC_Update(&hmac,rec->input,rec->length); HMAC_Final(&hmac,md,&md_size); HMAC_CTX_cleanup(&hmac); #ifdef TLS_DEBUG printf("sec="); {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); } printf("seq="); {int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); } printf("buf="); {int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); } printf("rec="); {unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); } #endif if ( SSL_version(ssl) != DTLS1_VERSION && SSL_version(ssl) != DTLS1_BAD_VER) { for (i=7; i>=0; i--) { ++seq[i]; if (seq[i] != 0) break; } } #ifdef TLS_DEBUG {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); } #endif return(md_size); }
unsigned char *mval2subsc(mval *in_val, gv_key *out_key, boolean_t std_null_coll) { boolean_t is_negative; unsigned char buf1[MAX_KEY_SZ + 1], ch, *cvt_table, *in_ptr, *out_ptr; unsigned char *tm, temp_mantissa[NUM_DEC_DG_2L / 2 + 3]; /* Need 1 byte for each two digits. Add 3 bytes slop */ mstr mstr_ch, mstr_buf1; int4 mt, mw, mx; uint4 mvt; /* Local copy of mvtype, bit ands use a int4, so do conversion once */ unsigned int digs, exp_val; int tmp_len, avail_bytes; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; /* The below assert is an attempt to catch between some and many of the cases where the mvtype is * not an accurate representation of the content. This can happen (and has) when there is a bug in * op_svput() where only the string portion of an mval is set without (re)setting the type leading * to numeric or num-approx values that do not represent reality and causing trouble especially with * subscripts. In that example, "-1" was left as a string with MV_NUM_APPROX on which caused a lot * of trouble with $ORDER in a database when -1 was treated as a string. This assert is not a 100% * catchall of invalid settings but it provides at least some barrier. A full barrier would require * complete conversion which is a bit expensive to always re-do at this point - even in a dbg version. * There is an exception though and that is if the caller is op_fnview. In that case, it could set * MV_NUM_APPROX to indicate a number needs to be treated as a string subscript. Skip that in the assert. */ assert(!(MV_NUM_APPROX & in_val->mvtype) || (NUM_DEC_DG_2L < in_val->str.len) || !val_iscan(in_val) || TREF(skip_mv_num_approx_assert)); out_ptr = out_key->base + out_key->end; if (TREF(transform) && gv_target->nct) { MV_FORCE_STR(in_val); mvt = in_val->mvtype | MV_NUM_APPROX; } else mvt = (uint4)in_val->mvtype; if (!(mvt & (MV_NM | MV_NUM_APPROX))) { /* Not currently in numeric form. Is it cannonical? */ if (val_iscan(in_val)) { /* Yes, convert it to numeric */ (void)s2n(in_val); mvt = in_val->mvtype; assert(mvt & MV_NM); } else { /* No, not numeric. Note the fact for future reference */ mvt = in_val->mvtype |= MV_NUM_APPROX; } } if (mvt & MV_NUM_APPROX) { /* It's a string */ in_ptr = (unsigned char *)in_val->str.addr; tmp_len = in_val->str.len; if (TREF(transform) && gv_target->collseq) { mstr_ch.len = tmp_len; mstr_ch.addr = (char *)in_ptr; mstr_buf1.len = SIZEOF(buf1); mstr_buf1.addr = (char *)buf1; do_xform(gv_target->collseq, XFORM, &mstr_ch, &mstr_buf1, &tmp_len); in_ptr = (unsigned char*)mstr_buf1.addr; /* mstr_buf1.addr is used just in case it is reallocated by the XFORM routine */ } /* Find out how much space is needed at a minimum to store the subscript representation of this string. * That would be STR_SUB_PREFIX + input string + at most TWO KEY_DELIMITER. * Assuming this, compute how much space would still be available in the out_key before reaching the top. * If this is negative, we have to signal a GVSUBOFLOW error. * If this is positive and the input string contains 0x00 or 0x01, we would need additional bytes to * store the STR_SUB_ESCAPE byte. Decrement the available space until it becomes zero * at which point issue a GVSUBOFLOW error as well. */ avail_bytes = out_key->top - (out_key->end + tmp_len + 3); if (0 > avail_bytes) ISSUE_GVSUBOFLOW_ERROR(out_key, KEY_COMPLETE_FALSE); if (0 < tmp_len) { *out_ptr++ = STR_SUB_PREFIX; do { ch = *in_ptr++; if (ch <= 1) { *out_ptr++ = STR_SUB_ESCAPE; if (0 > --avail_bytes) { /* Ensure input key to format_targ_key is double null terminated */ assert(STR_SUB_PREFIX == out_key->base[out_key->end]); out_key->base[out_key->end] = KEY_DELIMITER; ISSUE_GVSUBOFLOW_ERROR(out_key, KEY_COMPLETE_FALSE); } ch++; /* promote character */ } *out_ptr++ = ch; } while (--tmp_len > 0); } else *out_ptr++ = (0 == std_null_coll) ? STR_SUB_PREFIX : SUBSCRIPT_STDCOL_NULL; goto ALLDONE; } /* Its a number, is it an integer? But before this assert that we have enough allocated space in the key * to store the maximum possible numeric subscript and two terminating 0s at the end of the key */ assert((MAX_GVKEY_PADDING_LEN + 1) <= (int)(out_key->top - out_key->end)); if (mvt & MV_INT) { /* Yes, its an integer, convert it */ is_negative = FALSE; cvt_table = pos_code; if (0 > (mt = in_val->m[1])) { is_negative = TRUE; cvt_table = neg_code; mt = -mt; } else if (0 == mt) { *out_ptr++ = SUBSCRIPT_ZERO; goto ALLDONE; } if (10 > mt) { *out_ptr++ = is_negative ? ~(SUBSCRIPT_BIAS - 2) : (SUBSCRIPT_BIAS - 2); *out_ptr++ = cvt_table[mt * 10]; goto FINISH_NUMBER; } if (100 > mt) { *out_ptr++ = is_negative ? ~(SUBSCRIPT_BIAS - 1) : (SUBSCRIPT_BIAS - 1); *out_ptr++ = cvt_table[mt]; goto FINISH_NUMBER; } tm = temp_mantissa; if (1000 > mt) { exp_val = SUBSCRIPT_BIAS; goto ODD_INTEGER; } if (10000 > mt) { exp_val = SUBSCRIPT_BIAS + 1; goto EVEN_INTEGER; } if (100000 > mt) { exp_val = SUBSCRIPT_BIAS + 2; goto ODD_INTEGER; } if (1000000 > mt) { exp_val = SUBSCRIPT_BIAS + 3; goto EVEN_INTEGER; } if (10000000 > mt) { exp_val = SUBSCRIPT_BIAS + 4; goto ODD_INTEGER; } if (100000000 > mt) { exp_val = SUBSCRIPT_BIAS + 5; goto EVEN_INTEGER; } exp_val = SUBSCRIPT_BIAS + 6; ODD_INTEGER: *out_ptr++ = is_negative ? ~(exp_val) : (exp_val); mw = mx = mt / 10; mw *= 10; mw = mt - mw; mt = mx; if (mw) { *tm++ = cvt_table[mw * 10]; goto FINISH_INTEGERS; } goto KEEP_STRIPING; EVEN_INTEGER: *out_ptr++ = is_negative ? ~(exp_val) : (exp_val); KEEP_STRIPING: while (mt) { mw = mx = mt / 100; mw *= 100; mw = mt - mw; mt = mx; if (mw) { *tm++ = cvt_table[mw]; break; } } FINISH_INTEGERS: while (mt) { mw = mx = mt / 100; mw *= 100; mw = mt - mw; *tm++ = cvt_table[mw]; mt = mx; } while (tm > temp_mantissa) *out_ptr++ = *--tm; goto FINISH_NUMBER; } /* Convert 18 digit number */ cvt_table = pos_code; if (0 != (is_negative = in_val->sgn)) cvt_table = neg_code; *out_ptr++ = is_negative ? ~(in_val->e - MV_XBIAS + SUBSCRIPT_BIAS) : (in_val->e - MV_XBIAS + SUBSCRIPT_BIAS); mt = in_val->m[1]; mw = in_val->m[0]; /* Strip top two digits */ mx = mt / (MANT_HI / 100); *out_ptr++ = cvt_table[mx]; mt = (mt - (mx * (MANT_HI / 100))) * 100; /* * The two msd's have now been converted. The maximum number of * data remaining is 7 digits in "mt" and 9 digits in "mw". * If mw is zero, then we should just grind out mt till we are done */ if (0 == mw) goto LAST_LONGWORD; /* there are more than 7 digits left. First, we will put 8 digits in mt, (leaving 8 digits in mw) */ mx = mw / (MANT_HI / 10); mt += mx * 10; mw = (mw - (mx * (MANT_HI / 10))) * 10; if (0 == mw) goto LAST_LONGWORD; for (digs = 0; digs < 4; digs++) { mx = mt / (MANT_HI / 100); *out_ptr++ = cvt_table[mx]; mt = (mt - (mx * (MANT_HI / 100))) * 100; } mt = mw; LAST_LONGWORD: while (mt) { mx = mt / (MANT_HI / 100); *out_ptr++ = cvt_table[mx]; mt = (mt - (mx * (MANT_HI / 100))) * 100; } FINISH_NUMBER: if (is_negative) *out_ptr++ = NEG_MNTSSA_END; ALLDONE: *out_ptr++ = KEY_DELIMITER; *out_ptr = KEY_DELIMITER; out_key->prev = out_key->end; out_key->end = out_ptr - out_key->base; /* Check if after adding the current subscript and the second terminating NULL byte, there is still * MAX_GVKEY_PADDING_LEN bytes (allocated additionally as part of the DBKEYSIZE macro) left at the end. * If not, we have overflown the original max-key-size length. Issue error. */ if ((MAX_GVKEY_PADDING_LEN + 1) > (int)(out_key->top - out_key->end)) ISSUE_GVSUBOFLOW_ERROR(out_key, KEY_COMPLETE_FALSE); return out_ptr; }
int ssl23_get_client_hello(SSL *s) { char buf_space[11]; /* Request this many bytes in initial read. * We can detect SSL 3.0/TLS 1.0 Client Hellos * ('type == 3') correctly only when the following * is in a single record, which is not guaranteed by * the protocol specification: * Byte Content * 0 type \ * 1/2 version > record header * 3/4 length / * 5 msg_type \ * 6-8 length > Client Hello message * 9/10 client_version / */ char *buf= &(buf_space[0]); unsigned char *p,*d,*d_len,*dd; unsigned int i; unsigned int csl,sil,cl; int n=0,j; int type=0; int v[2]; if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { /* read the initial header */ v[0]=v[1]=0; if (!ssl3_setup_buffers(s)) goto err; n=ssl23_read_bytes(s, sizeof buf_space); if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */ p=s->packet; memcpy(buf,p,n); if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { /* * SSLv2 header */ if ((p[3] == 0x00) && (p[4] == 0x02)) { v[0]=p[3]; v[1]=p[4]; /* SSLv2 */ } else if (p[3] == SSL3_VERSION_MAJOR) { v[0]=p[3]; v[1]=p[4]; /* SSLv3/TLSv1 */ if (p[4] >= TLS1_VERSION_MINOR) { if (p[4] >= TLS1_2_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_2)) { s->version=TLS1_2_VERSION; s->state=SSL23_ST_SR_CLNT_HELLO_B; } else if (p[4] >= TLS1_1_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_1)) { s->version=TLS1_1_VERSION; /* type=2; */ /* done later to survive restarts */ s->state=SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_TLSv1)) { s->version=TLS1_VERSION; /* type=2; */ /* done later to survive restarts */ s->state=SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_SSLv3)) { s->version=SSL3_VERSION; /* type=2; */ s->state=SSL23_ST_SR_CLNT_HELLO_B; } } else if (!(s->options & SSL_OP_NO_SSLv3)) { s->version=SSL3_VERSION; /* type=2; */ s->state=SSL23_ST_SR_CLNT_HELLO_B; } } } else if ((p[0] == SSL3_RT_HANDSHAKE) && (p[1] == SSL3_VERSION_MAJOR) && (p[5] == SSL3_MT_CLIENT_HELLO) && ((p[3] == 0 && p[4] < 5 /* silly record length? */) || (p[9] >= p[1]))) { /* * SSLv3 or tls1 header */ v[0]=p[1]; /* major version (= SSL3_VERSION_MAJOR) */ /* We must look at client_version inside the Client Hello message * to get the correct minor version. * However if we have only a pathologically small fragment of the * Client Hello message, this would be difficult, and we'd have * to read more records to find out. * No known SSL 3.0 client fragments ClientHello like this, * so we simply reject such connections to avoid * protocol version downgrade attacks. */ if (p[3] == 0 && p[4] < 6) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL); goto err; } /* if major version number > 3 set minor to a value * which will use the highest version 3 we support. * If TLS 2.0 ever appears we will need to revise * this.... */ if (p[9] > SSL3_VERSION_MAJOR) v[1]=0xff; else v[1]=p[10]; /* minor version according to client_version */ if (v[1] >= TLS1_VERSION_MINOR) { if (v[1] >= TLS1_2_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_2)) { s->version=TLS1_2_VERSION; type=3; } else if (v[1] >= TLS1_1_VERSION_MINOR && !(s->options & SSL_OP_NO_TLSv1_1)) { s->version=TLS1_1_VERSION; type=3; } else if (!(s->options & SSL_OP_NO_TLSv1)) { s->version=TLS1_VERSION; type=3; } else if (!(s->options & SSL_OP_NO_SSLv3)) { s->version=SSL3_VERSION; type=3; } } else { /* client requests SSL 3.0 */ if (!(s->options & SSL_OP_NO_SSLv3)) { s->version=SSL3_VERSION; type=3; } else if (!(s->options & SSL_OP_NO_TLSv1)) { /* we won't be able to use TLS of course, * but this will send an appropriate alert */ s->version=TLS1_VERSION; type=3; } } } else if ((strncmp("GET ", (char *)p,4) == 0) || (strncmp("POST ",(char *)p,5) == 0) || (strncmp("HEAD ",(char *)p,5) == 0) || (strncmp("PUT ", (char *)p,4) == 0)) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTP_REQUEST); goto err; } else if (strncmp("CONNECT",(char *)p,7) == 0) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTPS_PROXY_REQUEST); goto err; } } /* ensure that TLS_MAX_VERSION is up-to-date */ OPENSSL_assert(s->version <= TLS_MAX_VERSION); if (s->version < TLS1_2_VERSION && tls1_suiteb(s)) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); goto err; } #ifdef OPENSSL_FIPS if (FIPS_mode() && (s->version < TLS1_VERSION)) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); goto err; } #endif if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_VERSION_TOO_LOW); goto err; } if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { /* we have SSLv3/TLSv1 in an SSLv2 header * (other cases skip this state) */ type=2; p=s->packet; v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ v[1] = p[4]; /* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 * header is sent directly on the wire, not wrapped as a TLS * record. It's format is: * Byte Content * 0-1 msg_length * 2 msg_type * 3-4 version * 5-6 cipher_spec_length * 7-8 session_id_length * 9-10 challenge_length * ... ... */ n=((p[0]&0x7f)<<8)|p[1]; if (n > (1024*4)) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE); goto err; } if (n < 9) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH); goto err; } j=ssl23_read_bytes(s,n+2); /* We previously read 11 bytes, so if j > 0, we must have * j == n+2 == s->packet_length. We have at least 11 valid * packet bytes. */ if (j <= 0) return(j); ssl3_finish_mac(s, s->packet+2, s->packet_length-2); if (s->msg_callback) s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */ p=s->packet; p+=5; n2s(p,csl); n2s(p,sil); n2s(p,cl); d=(unsigned char *)s->init_buf->data; if ((csl+sil+cl+11) != s->packet_length) /* We can't have TLS extensions in SSL 2.0 format * Client Hello, can we? Error condition should be * '>' otherweise */ { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH); goto err; } /* record header: msg_type ... */ *(d++) = SSL3_MT_CLIENT_HELLO; /* ... and length (actual value will be written later) */ d_len = d; d += 3; /* client_version */ *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ *(d++) = v[1]; /* lets populate the random area */ /* get the challenge_length */ i=(cl > SSL3_RANDOM_SIZE)?SSL3_RANDOM_SIZE:cl; memset(d,0,SSL3_RANDOM_SIZE); memcpy(&(d[SSL3_RANDOM_SIZE-i]),&(p[csl+sil]),i); d+=SSL3_RANDOM_SIZE; /* no session-id reuse */ *(d++)=0; /* ciphers */ j=0; dd=d; d+=2; for (i=0; i<csl; i+=3) { if (p[i] != 0) continue; *(d++)=p[i+1]; *(d++)=p[i+2]; j+=2; } s2n(j,dd); /* COMPRESSION */ *(d++)=1; *(d++)=0; #if 0 /* copy any remaining data with may be extensions */ p = p+csl+sil+cl; while (p < s->packet+s->packet_length) { *(d++)=*(p++); } #endif i = (d-(unsigned char *)s->init_buf->data) - 4; l2n3((long)i, d_len); /* get the data reused from the init_buf */ s->s3->tmp.reuse_message=1; s->s3->tmp.message_type=SSL3_MT_CLIENT_HELLO; s->s3->tmp.message_size=i; } /* imaginary new state (for program structure): */ /* s->state = SSL23_SR_CLNT_HELLO_C */ if ((type == 2) || (type == 3)) { /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */ const SSL_METHOD *new_method; new_method = ssl23_get_server_method(s->version); if (new_method == NULL) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); goto err; } s->method = new_method; if (!ssl_init_wbio_buffer(s,1)) goto err; /* we are in this state */ s->state=SSL3_ST_SR_CLNT_HELLO_A; if (type == 3) { /* put the 'n' bytes we have read into the input buffer * for SSLv3 */ s->rstate=SSL_ST_READ_HEADER; s->packet_length=n; if (s->s3->rbuf.buf == NULL) if (!ssl3_setup_read_buffer(s)) goto err; s->packet= &(s->s3->rbuf.buf[0]); memcpy(s->packet,buf,n); s->s3->rbuf.left=n; s->s3->rbuf.offset=0; } else { s->packet_length=0; s->s3->rbuf.left=0; s->s3->rbuf.offset=0; } #if 0 /* ssl3_get_client_hello does this */ s->client_version=(v[0]<<8)|v[1]; #endif s->handshake_func=s->method->ssl_accept; } else { /* bad, very bad */ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNKNOWN_PROTOCOL); goto err; } s->init_num=0; if (buf != buf_space) OPENSSL_free(buf); return(SSL_accept(s)); err: if (buf != buf_space) OPENSSL_free(buf); return(-1); }
int rwformat(void) { int n; mval key; oprtype x; triple *argcnt, *parm, *ref; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; ref = 0; for (;;) { switch (TREF(window_token)) { case TK_EXCLAIMATION: n = 0; do { n++; advancewindow(); } while (TK_EXCLAIMATION == TREF(window_token)); ref = maketriple(OC_WTEOL); ref->operand[0] = put_ilit(n); ins_triple(ref); break; case TK_HASH: advancewindow(); ref = newtriple(OC_WTFF); break; case TK_QUESTION: advancewindow(); if (EXPR_FAIL == expr(&x, MUMPS_INT)) return FALSE; ref = newtriple(OC_WTTAB); ref->operand[0] = x; return TRUE; case TK_SLASH: advancewindow(); if (TK_IDENT != TREF(window_token)) { stx_error(ERR_CTLMNEXPECTED); return FALSE; } assert(0 < (TREF(window_ident)).len); key.mvtype = MV_STR; key.str.len = (TREF(window_ident)).len; key.str.addr = (TREF(window_ident)).addr; s2n(&key); s2pool(&(key.str)); argcnt = parm = newtriple(OC_PARAMETER); parm->operand[0] = put_lit(&key); advancewindow(); n = 1; if (TK_LPAREN == TREF(window_token)) { advancewindow(); for (;;) { if (EXPR_FAIL == expr(&x, MUMPS_EXPR)) return FALSE; n++; ref = newtriple(OC_PARAMETER); ref->operand[0] = x; parm->operand[1] = put_tref(ref); parm = ref; if (TK_RPAREN == TREF(window_token)) { advancewindow(); break; } if (TK_COMMA != TREF(window_token)) { stx_error(ERR_COMMAORRPAREXP); return FALSE; } advancewindow(); } } ref = newtriple(OC_IOCONTROL); ref->operand[0] = put_ilit(n); ref->operand[1] = put_tref(argcnt); return TRUE; default: if (ref) return TRUE; stx_error(ERR_RWFORMAT); return FALSE; } } }
int dtls1_client_hello(SSL *s) { unsigned char *bufend, *d, *p; unsigned int i; if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { SSL_SESSION *sess = s->session; if ((s->session == NULL) || (s->session->ssl_version != s->version) || (!sess->session_id_length && !sess->tlsext_tick) || (s->session->not_resumable)) { if (!ssl_get_new_session(s, 0)) goto err; } /* else use the pre-loaded session */ p = s->s3->client_random; /* if client_random is initialized, reuse it, we are * required to use same upon reply to HelloVerify */ for (i = 0; p[i]=='\0' && i < sizeof(s->s3->client_random); i++) ; if (i == sizeof(s->s3->client_random)) arc4random_buf(p, sizeof(s->s3->client_random)); d = p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_HELLO); *(p++) = s->version >> 8; *(p++) = s->version&0xff; s->client_version = s->version; /* Random stuff */ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); p += SSL3_RANDOM_SIZE; /* Session ID */ if (s->new_session) i = 0; else i = s->session->session_id_length; *(p++) = i; if (i != 0) { if (i > sizeof s->session->session_id) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } memcpy(p, s->session->session_id, i); p += i; } /* cookie stuff */ if (s->d1->cookie_len > sizeof(s->d1->cookie)) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } *(p++) = s->d1->cookie_len; memcpy(p, s->d1->cookie, s->d1->cookie_len); p += s->d1->cookie_len; /* Ciphers supported */ i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]); if (i == 0) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); goto err; } s2n(i, p); p += i; /* add in (no) COMPRESSION */ *(p++) = 1; *(p++) = 0; /* Add the NULL method */ bufend = (unsigned char *)s->init_buf->data + SSL3_RT_MAX_PLAIN_LENGTH; if ((p = ssl_add_clienthello_tlsext(s, p, bufend)) == NULL) { SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } ssl3_handshake_msg_finish(s, p - d); s->state = SSL3_ST_CW_CLNT_HELLO_B; }
static int client_hello(SSL *s) { unsigned char *buf; unsigned char *p,*d; /* CIPHER **cipher;*/ int i,n,j; buf=(unsigned char *)s->init_buf->data; if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A) { if ((s->session == NULL) || (s->session->ssl_version != s->version)) { if (!ssl_get_new_session(s,0)) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); return(-1); } } /* else use the pre-loaded session */ p=buf; /* header */ d=p+9; /* data section */ *(p++)=SSL2_MT_CLIENT_HELLO; /* type */ s2n(SSL2_VERSION,p); /* version */ n=j=0; n=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),d); d+=n; if (n == 0) { SSLerr(SSL_F_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); return(-1); } s2n(n,p); /* cipher spec num bytes */ if ((s->session->session_id_length > 0) && (s->session->session_id_length <= SSL2_MAX_SSL_SESSION_ID_LENGTH)) { i=s->session->session_id_length; s2n(i,p); /* session id length */ memcpy(d,s->session->session_id,(unsigned int)i); d+=i; } else { s2n(0,p); } s->s2->challenge_length=SSL2_CHALLENGE_LENGTH; s2n(SSL2_CHALLENGE_LENGTH,p); /* challenge length */ /*challenge id data*/ if(RAND_pseudo_bytes(s->s2->challenge,SSL2_CHALLENGE_LENGTH) <= 0) return -1; memcpy(d,s->s2->challenge,SSL2_CHALLENGE_LENGTH); d+=SSL2_CHALLENGE_LENGTH; s->state=SSL2_ST_SEND_CLIENT_HELLO_B; s->init_num=d-buf; s->init_off=0; } /* SSL2_ST_SEND_CLIENT_HELLO_B */ return(ssl2_do_write(s)); }
int ssl23_get_client_hello(SSL *s) { char buf_space[11]; /* Request this many bytes in initial read. * We can detect SSL 3.0/TLS 1.0 Client Hellos * ('type == 3') correctly only when the following * is in a single record, which is not guaranteed by * the protocol specification: * Byte Content * 0 type \ * 1/2 version > record header * 3/4 length / * 5 msg_type \ * 6-8 length > Client Hello message * 9/10 client_version / */ char *buf= &(buf_space[0]); unsigned char *p,*d,*d_len,*dd; unsigned int i; unsigned int csl,sil,cl; int n=0,j; int type=0; int v[2]; if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { /* read the initial header */ v[0]=v[1]=0; if (!ssl3_setup_buffers(s)) goto err; n=ssl23_read_bytes(s, sizeof buf_space); if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */ p=s->packet; memcpy(buf,p,n); if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { /* * SSLv2 header */ if ((p[3] == 0x00) && (p[4] == 0x02)) { v[0]=p[3]; v[1]=p[4]; /* SSLv2 */ if (!(s->options & SSL_OP_NO_SSLv2)) type=1; } else if (p[3] == SSL3_VERSION_MAJOR) { v[0]=p[3]; v[1]=p[4]; /* SSLv3/TLSv1 */ if (p[4] >= TLS1_VERSION_MINOR) { if (!(s->options & SSL_OP_NO_TLSv1)) { s->version=TLS1_VERSION; /* type=2; */ /* done later to survive restarts */ s->state=SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_SSLv3)) { s->version=SSL3_VERSION; /* type=2; */ s->state=SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_SSLv2)) { type=1; } } else if (!(s->options & SSL_OP_NO_SSLv3)) { s->version=SSL3_VERSION; /* type=2; */ s->state=SSL23_ST_SR_CLNT_HELLO_B; } else if (!(s->options & SSL_OP_NO_SSLv2)) type=1; } } else if ((p[0] == SSL3_RT_HANDSHAKE) && (p[1] == SSL3_VERSION_MAJOR) && (p[5] == SSL3_MT_CLIENT_HELLO) && ((p[3] == 0 && p[4] < 5 /* silly record length? */) || (p[9] >= p[1]))) { /* * SSLv3 or tls1 header */ v[0]=p[1]; /* major version (= SSL3_VERSION_MAJOR) */ /* We must look at client_version inside the Client Hello message * to get the correct minor version. * However if we have only a pathologically small fragment of the * Client Hello message, this would be difficult, and we'd have * to read more records to find out. * No known SSL 3.0 client fragments ClientHello like this, * so we simply assume TLS 1.0 to avoid protocol version downgrade * attacks. */ if (p[3] == 0 && p[4] < 6) { #if 0 SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL); goto err; #else v[1] = TLS1_VERSION_MINOR; #endif } /* if major version number > 3 set minor to a value * which will use the highest version 3 we support. * If TLS 2.0 ever appears we will need to revise * this.... */ else if (p[9] > SSL3_VERSION_MAJOR) v[1]=0xff; else v[1]=p[10]; /* minor version according to client_version */ if (v[1] >= TLS1_VERSION_MINOR) { if (!(s->options & SSL_OP_NO_TLSv1)) { s->version=TLS1_VERSION; type=3; } else if (!(s->options & SSL_OP_NO_SSLv3)) { s->version=SSL3_VERSION; type=3; } } else { /* client requests SSL 3.0 */ if (!(s->options & SSL_OP_NO_SSLv3)) { s->version=SSL3_VERSION; type=3; } else if (!(s->options & SSL_OP_NO_TLSv1)) { /* we won't be able to use TLS of course, * but this will send an appropriate alert */ s->version=TLS1_VERSION; type=3; } } } else if ((strncmp("GET ", (char *)p,4) == 0) || (strncmp("POST ",(char *)p,5) == 0) || (strncmp("HEAD ",(char *)p,5) == 0) || (strncmp("PUT ", (char *)p,4) == 0)) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTP_REQUEST); goto err; } else if (strncmp("CONNECT",(char *)p,7) == 0) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTPS_PROXY_REQUEST); goto err; } } if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { /* we have SSLv3/TLSv1 in an SSLv2 header * (other cases skip this state) */ type=2; p=s->packet; v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ v[1] = p[4]; /* The SSL2 protocol allows n to be larger, just pick * a reasonable buffer size. */ #if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD #error "SSL3_RT_DEFAULT_PACKET_SIZE is too small." #endif n=((p[0]&0x7f)<<8)|p[1]; if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2) { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE); goto err; } j=ssl23_read_bytes(s,n+2); if (j <= 0) return(j); ssl3_finish_mac(s, s->packet+2, s->packet_length-2); if (s->msg_callback) s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */ p=s->packet; p+=5; n2s(p,csl); n2s(p,sil); n2s(p,cl); d=(unsigned char *)s->init_buf->data; if ((csl+sil+cl+11) != s->packet_length) /* We can't have TLS extensions in SSL 2.0 format * Client Hello, can we? Error condition should be * '>' otherweise */ { SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH); goto err; } /* record header: msg_type ... */ *(d++) = SSL3_MT_CLIENT_HELLO; /* ... and length (actual value will be written later) */ d_len = d; d += 3; /* client_version */ *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ *(d++) = v[1]; /* lets populate the random area */ /* get the challenge_length */ i=(cl > SSL3_RANDOM_SIZE)?SSL3_RANDOM_SIZE:cl; memset(d,0,SSL3_RANDOM_SIZE); memcpy(&(d[SSL3_RANDOM_SIZE-i]),&(p[csl+sil]),i); d+=SSL3_RANDOM_SIZE; /* no session-id reuse */ *(d++)=0; /* ciphers */ j=0; dd=d; d+=2; for (i=0; i<csl; i+=3) { if (p[i] != 0) continue; *(d++)=p[i+1]; *(d++)=p[i+2]; j+=2; } s2n(j,dd); /* COMPRESSION */ *(d++)=1; *(d++)=0; #if 0 /* copy any remaining data with may be extensions */ p = p+csl+sil+cl; while (p < s->packet+s->packet_length) { *(d++)=*(p++); } #endif i = (d-(unsigned char *)s->init_buf->data) - 4; l2n3((long)i, d_len); /* get the data reused from the init_buf */ s->s3->tmp.reuse_message=1; s->s3->tmp.message_type=SSL3_MT_CLIENT_HELLO; s->s3->tmp.message_size=i; } /* imaginary new state (for program structure): */ /* s->state = SSL23_SR_CLNT_HELLO_C */ if (type == 1) { #ifdef OPENSSL_NO_SSL2 SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); goto err; #else /* we are talking sslv2 */ /* we need to clean up the SSLv3/TLSv1 setup and put in the * sslv2 stuff. */ if (s->s2 == NULL) { if (!ssl2_new(s)) goto err; } else ssl2_clear(s); if (s->s3 != NULL) ssl3_free(s); if (!BUF_MEM_grow_clean(s->init_buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { goto err; } s->state=SSL2_ST_GET_CLIENT_HELLO_A; if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3) s->s2->ssl2_rollback=0; else /* reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0 * (SSL 3.0 draft/RFC 2246, App. E.2) */ s->s2->ssl2_rollback=1; /* setup the n bytes we have read so we get them from * the sslv2 buffer */ s->rstate=SSL_ST_READ_HEADER; s->packet_length=n; s->packet= &(s->s2->rbuf[0]); memcpy(s->packet,buf,n); s->s2->rbuf_left=n; s->s2->rbuf_offs=0; s->method=SSLv2_server_method(); s->handshake_func=s->method->ssl_accept; #endif } if ((type == 2) || (type == 3)) { /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */ if (!ssl_init_wbio_buffer(s,1)) goto err; /* we are in this state */ s->state=SSL3_ST_SR_CLNT_HELLO_A; if (type == 3) { /* put the 'n' bytes we have read into the input buffer * for SSLv3 */ s->rstate=SSL_ST_READ_HEADER; s->packet_length=n; if (s->s3->rbuf.buf == NULL) if (!ssl3_setup_read_buffer(s)) goto err; s->packet= &(s->s3->rbuf.buf[0]); memcpy(s->packet,buf,n); s->s3->rbuf.left=n; s->s3->rbuf.offset=0; } else { s->packet_length=0; s->s3->rbuf.left=0; s->s3->rbuf.offset=0; } if (s->version == TLS1_VERSION) s->method = TLSv1_server_method(); else s->method = SSLv3_server_method(); #if 0 /* ssl3_get_client_hello does this */ s->client_version=(v[0]<<8)|v[1]; #endif s->handshake_func=s->method->ssl_accept; } if ((type < 1) || (type > 3)) { /* bad, very bad */ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNKNOWN_PROTOCOL); goto err; } s->init_num=0; if (buf != buf_space) OPENSSL_free(buf); return(SSL_accept(s)); err: if (buf != buf_space) OPENSSL_free(buf); return(-1); }
static int client_master_key(SSL *s) { unsigned char *buf; unsigned char *p,*d; int clear,enc,karg,i; SSL_SESSION *sess; const EVP_CIPHER *c; const EVP_MD *md; buf=(unsigned char *)s->init_buf->data; if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A) { if (!ssl_cipher_get_evp(s->session,&c,&md,NULL)) { ssl2_return_error(s,SSL2_PE_NO_CIPHER); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); return(-1); } sess=s->session; p=buf; d=p+10; *(p++)=SSL2_MT_CLIENT_MASTER_KEY;/* type */ i=ssl_put_cipher_by_char(s,sess->cipher,p); p+=i; /* make key_arg data */ i=EVP_CIPHER_iv_length(c); sess->key_arg_length=i; if (i > SSL_MAX_KEY_ARG_LENGTH) { ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } if (i > 0) if(RAND_pseudo_bytes(sess->key_arg,i) <= 0) return -1; /* make a master key */ i=EVP_CIPHER_key_length(c); sess->master_key_length=i; if (i > 0) { if (i > sizeof sess->master_key) { ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } if (RAND_bytes(sess->master_key,i) <= 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); return(-1); } } if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) enc=8; else if (SSL_C_IS_EXPORT(sess->cipher)) enc=5; else enc=i; if (i < enc) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_CIPHER_TABLE_SRC_ERROR); return(-1); } clear=i-enc; s2n(clear,p); memcpy(d,sess->master_key,(unsigned int)clear); d+=clear; enc=ssl_rsa_public_encrypt(sess->sess_cert,enc, &(sess->master_key[clear]),d, (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING); if (enc <= 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PUBLIC_KEY_ENCRYPT_ERROR); return(-1); } #ifdef PKCS1_CHECK if (s->options & SSL_OP_PKCS1_CHECK_1) d[1]++; if (s->options & SSL_OP_PKCS1_CHECK_2) sess->master_key[clear]++; #endif s2n(enc,p); d+=enc; karg=sess->key_arg_length; s2n(karg,p); /* key arg size */ if (karg > sizeof sess->key_arg) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } memcpy(d,sess->key_arg,(unsigned int)karg); d+=karg; s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_B; s->init_num=d-buf; s->init_off=0; } /* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */ return(ssl2_do_write(s)); }
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) { int extdatalen=0; unsigned char *ret = p; ret+=2; if (ret>=limit) return NULL; /* this really never occurs, but ... */ if (s->tlsext_hostname != NULL) { /* Add TLS extension servername to the Client Hello message */ unsigned long size_str; long lenmax; /* check for enough space. 4 for the servername type and entension length 2 for servernamelist length 1 for the hostname type 2 for hostname length + hostname length */ if ((lenmax = limit - ret - 9) < 0 || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) return NULL; /* extension type and length */ s2n(TLSEXT_TYPE_server_name,ret); s2n(size_str+5,ret); /* length of servername list */ s2n(size_str+3,ret); /* hostname type, length and hostname */ *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name; s2n(size_str,ret); memcpy(ret, s->tlsext_hostname, size_str); ret+=size_str; } if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { int ticklen; if (s->session && s->session->tlsext_tick) ticklen = s->session->tlsext_ticklen; else ticklen = 0; /* Check for enough room 2 for extension type, 2 for len * rest for ticket */ if (limit - ret - 4 - ticklen < 0) return NULL; s2n(TLSEXT_TYPE_session_ticket,ret); s2n(ticklen,ret); if (ticklen) { memcpy(ret, s->session->tlsext_tick, ticklen); ret += ticklen; } } if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { int i; long extlen, idlen, itmp; OCSP_RESPID *id; idlen = 0; for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); itmp = i2d_OCSP_RESPID(id, NULL); if (itmp <= 0) return NULL; idlen += itmp + 2; } if (s->tlsext_ocsp_exts) { extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); if (extlen < 0) return NULL; } else extlen = 0; if ((long)(limit - ret - 7 - extlen - idlen) < 0) return NULL; s2n(TLSEXT_TYPE_status_request, ret); if (extlen + idlen > 0xFFF0) return NULL; s2n(extlen + idlen + 5, ret); *(ret++) = TLSEXT_STATUSTYPE_ocsp; s2n(idlen, ret); for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { /* save position of id len */ unsigned char *q = ret; id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); /* skip over id len */ ret += 2; itmp = i2d_OCSP_RESPID(id, &ret); /* write id len */ s2n(itmp, q); } s2n(extlen, ret); if (extlen > 0) i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret); } if ((extdatalen = ret-p-2)== 0) return p; s2n(extdatalen,p); return ret; }