You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2017/11/21 08:46:43 UTC

[trafficserver] branch quic-latest updated: Fix 1-rtt packet protection

This is an automated email from the ASF dual-hosted git repository.

maskit pushed a commit to branch quic-latest
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/quic-latest by this push:
     new f91516c  Fix 1-rtt packet protection
f91516c is described below

commit f91516c61c74d25f30516a1e372d376ea4c48ba4
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Tue Nov 21 17:46:12 2017 +0900

    Fix 1-rtt packet protection
---
 iocore/net/quic/QUICCrypto.cc       | 10 +++++---
 iocore/net/quic/QUICHandshake.cc    | 10 ++++----
 iocore/net/quic/QUICKeyGenerator.cc | 13 +++++-----
 iocore/net/quic/QUICPacket.cc       | 47 +++++++++----------------------------
 iocore/net/quic/QUICPacket.h        | 14 +----------
 5 files changed, 30 insertions(+), 64 deletions(-)

diff --git a/iocore/net/quic/QUICCrypto.cc b/iocore/net/quic/QUICCrypto.cc
index 9041ad5..02231eb 100644
--- a/iocore/net/quic/QUICCrypto.cc
+++ b/iocore/net/quic/QUICCrypto.cc
@@ -155,7 +155,7 @@ QUICCryptoTls::handshake(uint8_t *out, size_t &out_len, size_t max_out_len, cons
 bool
 QUICCryptoTls::is_handshake_finished() const
 {
-  return SSL_is_init_finished(this->_ssl);
+  return (this->_client_pp->key_phase() != QUICKeyPhase::CLEARTEXT && this->_server_pp->key_phase() != QUICKeyPhase::CLEARTEXT);
 }
 
 int
@@ -177,7 +177,7 @@ QUICCryptoTls::initialize_key_materials(QUICConnectionId cid)
 int
 QUICCryptoTls::update_key_materials()
 {
-  ink_assert(this->is_handshake_finished());
+  ink_assert(SSL_is_init_finished(this->_ssl));
   // Switch key phase
   QUICKeyPhase next_key_phase;
   switch (this->_client_pp->key_phase()) {
@@ -256,7 +256,11 @@ QUICCryptoTls::decrypt(uint8_t *plain, size_t &plain_len, size_t max_plain_len,
   }
 
   size_t tag_len = this->_get_aead_tag_len();
-  return _decrypt(plain, plain_len, max_plain_len, cipher, cipher_len, pkt_num, ad, ad_len, pp->get_key(phase), tag_len);
+  bool ret       = _decrypt(plain, plain_len, max_plain_len, cipher, cipher_len, pkt_num, ad, ad_len, pp->get_key(phase), tag_len);
+  if (!ret) {
+    Debug(tag, "Failed to decrypt a packet: pkt_num=%" PRIu64, pkt_num);
+  }
+  return ret;
 }
 
 /**
diff --git a/iocore/net/quic/QUICHandshake.cc b/iocore/net/quic/QUICHandshake.cc
index faf2c1c..2a3b75e 100644
--- a/iocore/net/quic/QUICHandshake.cc
+++ b/iocore/net/quic/QUICHandshake.cc
@@ -379,18 +379,16 @@ QUICHandshake::_process_client_finished()
     I_WANNA_DUMP_THIS_BUF(out, static_cast<int64_t>(out_len));
     // <----- DEBUG -----
 
-    ink_assert(this->_crypto->is_handshake_finished());
-    DebugQHS("Handshake is completed");
-
     _process_handshake_complete();
+    DebugQHS("Handshake has been completed");
+
+    DebugQHS("Enter state_complete");
+    SET_HANDLER(&QUICHandshake::state_complete);
 
     stream_io->write(out, out_len);
     stream_io->write_reenable();
     stream_io->read_reenable();
 
-    DebugQHS("Enter state_complete");
-    SET_HANDLER(&QUICHandshake::state_complete);
-
     return QUICErrorUPtr(new QUICNoError());
   } else {
     return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::TLS_HANDSHAKE_FAILED));
diff --git a/iocore/net/quic/QUICKeyGenerator.cc b/iocore/net/quic/QUICKeyGenerator.cc
index a9aba4e..10ec80c 100644
--- a/iocore/net/quic/QUICKeyGenerator.cc
+++ b/iocore/net/quic/QUICKeyGenerator.cc
@@ -23,6 +23,7 @@
 
 #include <openssl/ssl.h>
 #include "QUICKeyGenerator.h"
+#include "ts/ink_assert.h"
 #include "ts/HKDF.h"
 
 constexpr static uint8_t QUIC_VERSION_1_SALT[] = {
@@ -126,15 +127,15 @@ int
 QUICKeyGenerator::_generate_pp_secret(uint8_t *out, size_t *out_len, HKDF &hkdf, SSL *ssl, const char *label, size_t label_len,
                                       size_t length)
 {
-  uint8_t secret[512];
-  size_t secret_len = length;
+  *out_len = length;
   if (this->_last_secret_len == 0) {
-    SSL_export_keying_material(ssl, secret, secret_len, label, label_len, reinterpret_cast<const uint8_t *>(""), 0, 1);
+    SSL_export_keying_material(ssl, out, *out_len, label, label_len, reinterpret_cast<const uint8_t *>(""), 0, 1);
   } else {
+    ink_assert(!"not implemented");
   }
-  memcpy(this->_last_secret, secret, secret_len);
-  this->_last_secret_len = secret_len;
-  *out_len               = length;
+
+  memcpy(this->_last_secret, out, *out_len);
+  this->_last_secret_len = *out_len;
 
   return 0;
 }
diff --git a/iocore/net/quic/QUICPacket.cc b/iocore/net/quic/QUICPacket.cc
index 35e55d4..fb7c348 100644
--- a/iocore/net/quic/QUICPacket.cc
+++ b/iocore/net/quic/QUICPacket.cc
@@ -481,20 +481,6 @@ QUICPacket::QUICPacket(QUICPacketHeader *header, ats_unique_buf payload, size_t
   this->_is_retransmittable = retransmittable;
 }
 
-QUICPacket::QUICPacket(QUICPacketType type, QUICPacketNumber packet_number, QUICPacketNumber base_packet_number,
-                       ats_unique_buf payload, size_t len, bool retransmittable)
-{
-  this->_header             = QUICPacketHeader::build(type, packet_number, base_packet_number, std::move(payload), len);
-  this->_is_retransmittable = retransmittable;
-}
-
-QUICPacket::QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number,
-                       QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len, bool retransmittable)
-{
-  this->_header = QUICPacketHeader::build(type, connection_id, packet_number, base_packet_number, std::move(payload), len);
-  this->_is_retransmittable = retransmittable;
-}
-
 QUICPacket::QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICStatelessToken stateless_reset_token)
 {
   const uint8_t *token                     = stateless_reset_token.get_u8();
@@ -762,35 +748,24 @@ QUICPacketUPtr
 QUICPacketFactory::create_server_protected_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number,
                                                   ats_unique_buf payload, size_t len, bool retransmittable)
 {
-  // TODO Key phase should be picked up from QUICCrypto, probably
-  QUICPacket *p = quicPacketAllocator.alloc();
-  new (p) QUICPacket(QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0, connection_id, this->_packet_number_generator.next(),
-                     base_packet_number, std::move(payload), len, retransmittable);
-  auto packet = QUICPacketUPtr(p, &QUICPacketDeleter::delete_packet);
-
   // TODO: use pmtu of UnixNetVConnection
   size_t max_cipher_txt_len = 2048;
   ats_unique_buf cipher_txt = ats_unique_malloc(max_cipher_txt_len);
   size_t cipher_txt_len     = 0;
 
-  // TODO: do not dump header twice
-  uint8_t ad[17] = {0};
-  size_t ad_len  = 0;
-  packet->header()->store(ad, &ad_len);
-
-  if (this->_crypto->encrypt(cipher_txt.get(), cipher_txt_len, max_cipher_txt_len, packet->payload(), packet->payload_size(),
-                             packet->packet_number(), ad, ad_len, packet->key_phase())) {
-    QUICPacket *ep = quicPacketAllocator.alloc();
-    new (ep) QUICPacket(packet->header()->clone(), std::move(cipher_txt), cipher_txt_len, base_packet_number);
-    packet = QUICPacketUPtr(ep, &QUICPacketDeleter::delete_packet);
+  // TODO Key phase should be picked up from QUICCrypto, probably
+  QUICPacket *packet = nullptr;
+  QUICPacketHeader *header =
+    QUICPacketHeader::build(QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0, connection_id, this->_packet_number_generator.next(),
+                            base_packet_number, std::move(payload), len);
 
-    Debug("quic_packet_factory", "Encrypt Packet, pkt_num: %" PRIu64 ", header_len: %zu payload: %zu", packet->packet_number(),
-          ad_len, cipher_txt_len);
-    return packet;
-  } else {
-    Debug("quic_packet_factory", "CRYPTOGRAPHIC Error");
-    return QUICPacketUPtr(nullptr, &QUICPacketDeleter::delete_null_packet);
+  if (this->_crypto->encrypt(cipher_txt.get(), cipher_txt_len, max_cipher_txt_len, header->payload(), header->payload_size(),
+                             header->packet_number(), header->buf(), header->length(), header->key_phase())) {
+    packet = quicPacketAllocator.alloc();
+    new (packet) QUICPacket(header, std::move(cipher_txt), cipher_txt_len, retransmittable);
   }
+
+  return QUICPacketUPtr(packet, &QUICPacketDeleter::delete_packet);
 }
 
 QUICPacketUPtr
diff --git a/iocore/net/quic/QUICPacket.h b/iocore/net/quic/QUICPacket.h
index b7173ed..fd390e3 100644
--- a/iocore/net/quic/QUICPacket.h
+++ b/iocore/net/quic/QUICPacket.h
@@ -195,7 +195,7 @@ public:
   QUICPacket(QUICPacketHeader *header, ats_unique_buf payload, size_t payload_len);
 
   /*
-   * Creates a QUICPacket with a QUICPacketHeader, a buffer that contains payload and a flag that indicates whether the packet can
+   * Creates a QUICPacket with a QUICPacketHeader, a buffer that contains payload and a flag that indicates whether the packet is
    * retransmittable
    *
    * This will be used for sending packets. Therefore, it is expected that payload is already encrypted.
@@ -204,18 +204,6 @@ public:
   QUICPacket(QUICPacketHeader *header, ats_unique_buf payload, size_t payload_len, bool retransmittable);
 
   /*
-   * Creates a QUICPacket that has a Short Header
-   */
-  QUICPacket(QUICPacketType type, QUICPacketNumber packet_number, QUICPacketNumber base_packet_number, ats_unique_buf payload,
-             size_t len, bool retransmittable);
-
-  /*
-   * Creates a QUICPacket that has a Short Header with a Connection ID
-   */
-  QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number,
-             QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len, bool retransmittabl);
-
-  /*
    * Creates a QUICpacket for stateless reset
    */
   QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICStatelessToken stateless_reset_token);

-- 
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].