Added macro that indicates presence of the time callback feature. Also added C++...
[BearSSL] / src / ssl / ssl_engine.c
index 1022d87..f59fe1a 100644 (file)
@@ -1232,6 +1232,21 @@ void
 br_ssl_engine_close(br_ssl_engine_context *cc)
 {
        if (!br_ssl_engine_closed(cc)) {
+               /*
+                * If we are not already closed, then we need to
+                * initiate the closure. Once closing, any incoming
+                * application data is discarded; we should also discard
+                * application data which is already there but has not
+                * been acknowledged by the application yet (this mimics
+                * usual semantics on BSD sockets: you cannot read()
+                * once you called close(), even if there was some
+                * unread data already buffered).
+                */
+               size_t len;
+
+               if (br_ssl_engine_recvapp_buf(cc, &len) != NULL && len != 0) {
+                       br_ssl_engine_recvapp_ack(cc, len);
+               }
                jump_handshake(cc, 1);
        }
 }
@@ -1522,3 +1537,48 @@ br_ssl_engine_switch_chapol_out(br_ssl_engine_context *cc,
        cc->ichapol_out->init(&cc->out.chapol.vtable.out,
                cc->ichacha, cc->ipoly, cipher_key, iv);
 }
+
+/* see inner.h */
+void
+br_ssl_engine_switch_ccm_in(br_ssl_engine_context *cc,
+       int is_client, int prf_id,
+       const br_block_ctrcbc_class *bc_impl,
+       size_t cipher_key_len, size_t tag_len)
+{
+       unsigned char kb[72];
+       unsigned char *cipher_key, *iv;
+
+       compute_key_block(cc, prf_id, cipher_key_len + 4, kb);
+       if (is_client) {
+               cipher_key = &kb[cipher_key_len];
+               iv = &kb[(cipher_key_len << 1) + 4];
+       } else {
+               cipher_key = &kb[0];
+               iv = &kb[cipher_key_len << 1];
+       }
+       cc->iccm_in->init(&cc->in.ccm.vtable.in,
+               bc_impl, cipher_key, cipher_key_len, iv, tag_len);
+       cc->incrypt = 1;
+}
+
+/* see inner.h */
+void
+br_ssl_engine_switch_ccm_out(br_ssl_engine_context *cc,
+       int is_client, int prf_id,
+       const br_block_ctrcbc_class *bc_impl,
+       size_t cipher_key_len, size_t tag_len)
+{
+       unsigned char kb[72];
+       unsigned char *cipher_key, *iv;
+
+       compute_key_block(cc, prf_id, cipher_key_len + 4, kb);
+       if (is_client) {
+               cipher_key = &kb[0];
+               iv = &kb[cipher_key_len << 1];
+       } else {
+               cipher_key = &kb[cipher_key_len];
+               iv = &kb[(cipher_key_len << 1) + 4];
+       }
+       cc->iccm_out->init(&cc->out.ccm.vtable.out,
+               bc_impl, cipher_key, cipher_key_len, iv, tag_len);
+}