📄 d1_pkt.c
字号:
#endif p = wb->buf + prefix_len; /* write the header */ *(p++)=type&0xff; wr->type=type; *(p++)=(s->version>>8); *(p++)=s->version&0xff; /* field where we are to write out packet epoch, seq num and len */ pseq=p; p+=10; /* lets setup the record stuff. */ /* Make space for the explicit IV in case of CBC. * (this is a bit of a boundary violation, but what the heck). */ if ( s->enc_write_ctx && (EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE)) bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher); else bs = 0; wr->data=p + bs; /* make room for IV in case of CBC */ wr->length=(int)len; wr->input=(unsigned char *)buf; /* we now 'read' from wr->input, wr->length bytes into * wr->data */ /* first we compress */ if (s->compress != NULL) { if (!ssl3_do_compress(s)) { SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE); goto err; } } else { memcpy(wr->data,wr->input,wr->length); wr->input=wr->data; } /* we should still have the output to wr->data and the input * from wr->input. Length should be wr->length. * wr->data still points in the wb->buf */ if (mac_size != 0) { s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1); wr->length+=mac_size; } /* this is true regardless of mac size */ wr->input=p; wr->data=p; /* ssl3_enc can only have an error on read */ wr->length += bs; /* bs != 0 in case of CBC. The enc fn provides * the randomness */ s->method->ssl3_enc->enc(s,1); /* record length after mac and block padding *//* if (type == SSL3_RT_APPLICATION_DATA || (type == SSL3_RT_ALERT && ! SSL_in_init(s))) */ /* there's only one epoch between handshake and app data */ s2n(s->d1->w_epoch, pseq); /* XDTLS: ?? *//* else s2n(s->d1->handshake_epoch, pseq); */ memcpy(pseq, &(s->s3->write_sequence[2]), 6); pseq+=6; s2n(wr->length,pseq); /* we should now have * wr->data pointing to the encrypted data, which is * wr->length long */ wr->type=type; /* not needed but helps for debugging */ wr->length+=DTLS1_RT_HEADER_LENGTH;#if 0 /* this is now done at the message layer */ /* buffer the record, making it easy to handle retransmits */ if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC) dtls1_buffer_record(s, wr->data, wr->length, *((PQ_64BIT *)&(s->s3->write_sequence[0])));#endif ssl3_record_sequence_update(&(s->s3->write_sequence[0])); if (create_empty_fragment) { /* we are in a recursive call; * just return the length, don't write out anything here */ return wr->length; } /* now let's set up wb */ wb->left = prefix_len + wr->length; wb->offset = 0; /* memorize arguments so that ssl3_write_pending can detect bad write retries later */ s->s3->wpend_tot=len; s->s3->wpend_buf=buf; s->s3->wpend_type=type; s->s3->wpend_ret=len; /* we now just need to write the buffer */ return ssl3_write_pending(s,type,buf,len);err: return -1; }static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, PQ_64BIT *seq_num) {#if PQ_64BIT_IS_INTEGER PQ_64BIT mask = 0x0000000000000001L;#endif PQ_64BIT rcd_num, tmp; pq_64bit_init(&rcd_num); pq_64bit_init(&tmp); /* this is the sequence number for the record just read */ pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8); if (pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) || pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num))) { pq_64bit_assign(seq_num, &rcd_num); pq_64bit_free(&rcd_num); pq_64bit_free(&tmp); return 1; /* this record is new */ } pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num); if ( pq_64bit_get_word(&tmp) > bitmap->length) { pq_64bit_free(&rcd_num); pq_64bit_free(&tmp); return 0; /* stale, outside the window */ }#if PQ_64BIT_IS_BIGNUM { int offset; pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num); pq_64bit_sub_word(&tmp, 1); offset = pq_64bit_get_word(&tmp); if ( pq_64bit_is_bit_set(&(bitmap->map), offset)) { pq_64bit_free(&rcd_num); pq_64bit_free(&tmp); return 0; } }#else mask <<= (bitmap->max_seq_num - rcd_num - 1); if (bitmap->map & mask) return 0; /* record previously received */#endif pq_64bit_assign(seq_num, &rcd_num); pq_64bit_free(&rcd_num); pq_64bit_free(&tmp); return 1; }static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) { unsigned int shift; PQ_64BIT rcd_num; PQ_64BIT tmp; PQ_64BIT_CTX *ctx; pq_64bit_init(&rcd_num); pq_64bit_init(&tmp); pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8); /* unfortunate code complexity due to 64-bit manipulation support * on 32-bit machines */ if ( pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) || pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num))) { pq_64bit_sub(&tmp, &rcd_num, &(bitmap->max_seq_num)); pq_64bit_add_word(&tmp, 1); shift = (unsigned int)pq_64bit_get_word(&tmp); pq_64bit_lshift(&(tmp), &(bitmap->map), shift); pq_64bit_assign(&(bitmap->map), &tmp); pq_64bit_set_bit(&(bitmap->map), 0); pq_64bit_add_word(&rcd_num, 1); pq_64bit_assign(&(bitmap->max_seq_num), &rcd_num); pq_64bit_assign_word(&tmp, 1); pq_64bit_lshift(&tmp, &tmp, bitmap->length); ctx = pq_64bit_ctx_new(&ctx); pq_64bit_mod(&(bitmap->map), &(bitmap->map), &tmp, ctx); pq_64bit_ctx_free(ctx); } else { pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num); pq_64bit_sub_word(&tmp, 1); shift = (unsigned int)pq_64bit_get_word(&tmp); pq_64bit_set_bit(&(bitmap->map), shift); } pq_64bit_free(&rcd_num); pq_64bit_free(&tmp); }int dtls1_dispatch_alert(SSL *s) { int i,j; void (*cb)(const SSL *ssl,int type,int val)=NULL; unsigned char buf[2 + 2 + 3]; /* alert level + alert desc + message seq +frag_off */ unsigned char *ptr = &buf[0]; s->s3->alert_dispatch=0; memset(buf, 0x00, sizeof(buf)); *ptr++ = s->s3->send_alert[0]; *ptr++ = s->s3->send_alert[1]; if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { s2n(s->d1->handshake_read_seq, ptr);#if 0 if ( s->d1->r_msg_hdr.frag_off == 0) /* waiting for a new msg */ else s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */#endif#if 0 fprintf(stderr, "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",s->d1->handshake_read_seq,s->d1->r_msg_hdr.seq);#endif l2n3(s->d1->r_msg_hdr.frag_off, ptr); } i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); if (i <= 0) { s->s3->alert_dispatch=1; /* fprintf( stderr, "not done with alert\n" ); */ } else { if ( s->s3->send_alert[0] == SSL3_AL_FATAL || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) (void)BIO_flush(s->wbio); if (s->msg_callback) s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s, s->msg_callback_arg); if (s->info_callback != NULL) cb=s->info_callback; else if (s->ctx->info_callback != NULL) cb=s->ctx->info_callback; if (cb != NULL) { j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1]; cb(s,SSL_CB_WRITE_ALERT,j); } } return(i); }static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch) { *is_next_epoch = 0; /* In current epoch, accept HM, CCS, DATA, & ALERT */ if (rr->epoch == s->d1->r_epoch) return &s->d1->bitmap; /* Only HM and ALERT messages can be from the next epoch */ else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { *is_next_epoch = 1; return &s->d1->next_bitmap; } return NULL; }#if 0static intdtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority, unsigned long *offset) { /* alerts are passed up immediately */ if ( rr->type == SSL3_RT_APPLICATION_DATA || rr->type == SSL3_RT_ALERT) return 0; /* Only need to buffer if a handshake is underway. * (this implies that Hello Request and Client Hello are passed up * immediately) */ if ( SSL_in_init(s)) { unsigned char *data = rr->data; /* need to extract the HM/CCS sequence number here */ if ( rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { unsigned short seq_num; struct hm_header_st msg_hdr; struct ccs_header_st ccs_hdr; if ( rr->type == SSL3_RT_HANDSHAKE) { dtls1_get_message_header(data, &msg_hdr); seq_num = msg_hdr.seq; *offset = msg_hdr.frag_off; } else { dtls1_get_ccs_header(data, &ccs_hdr); seq_num = ccs_hdr.seq; *offset = 0; } /* this is either a record we're waiting for, or a * retransmit of something we happened to previously * receive (higher layers will drop the repeat silently */ if ( seq_num < s->d1->handshake_read_seq) return 0; if (rr->type == SSL3_RT_HANDSHAKE && seq_num == s->d1->handshake_read_seq && msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off) return 0; else if ( seq_num == s->d1->handshake_read_seq && (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC || msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off)) return 0; else { *priority = seq_num; return 1; } } else /* unknown record type */ return 0; } return 0; }#endifvoiddtls1_reset_seq_numbers(SSL *s, int rw) { unsigned char *seq; unsigned int seq_bytes = sizeof(s->s3->read_sequence); if ( rw & SSL3_CC_READ) { seq = s->s3->read_sequence; s->d1->r_epoch++; pq_64bit_assign(&(s->d1->bitmap.map), &(s->d1->next_bitmap.map)); s->d1->bitmap.length = s->d1->next_bitmap.length; pq_64bit_assign(&(s->d1->bitmap.max_seq_num), &(s->d1->next_bitmap.max_seq_num)); pq_64bit_free(&(s->d1->next_bitmap.map)); pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); pq_64bit_init(&(s->d1->next_bitmap.map)); pq_64bit_init(&(s->d1->next_bitmap.max_seq_num)); } else { seq = s->s3->write_sequence; s->d1->w_epoch++; } memset(seq, 0x00, seq_bytes); }#if PQ_64BIT_IS_INTEGERstatic PQ_64BITbytes_to_long_long(unsigned char *bytes, PQ_64BIT *num) { PQ_64BIT _num; _num = (((PQ_64BIT)bytes[0]) << 56) | (((PQ_64BIT)bytes[1]) << 48) | (((PQ_64BIT)bytes[2]) << 40) | (((PQ_64BIT)bytes[3]) << 32) | (((PQ_64BIT)bytes[4]) << 24) | (((PQ_64BIT)bytes[5]) << 16) | (((PQ_64BIT)bytes[6]) << 8) | (((PQ_64BIT)bytes[7]) ); *num = _num ; return _num; }#endifstatic voiddtls1_clear_timeouts(SSL *s) { memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -