]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
tests: check the sequence numbers produced by gnutls_record_get_state()
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 29 Mar 2016 12:11:56 +0000 (14:11 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 29 Mar 2016 12:11:56 +0000 (14:11 +0200)
tests/mini-key-material.c

index 688cddcc07de3fe55f6a3531209d33846a01c5e7..ddd64de8fd45bcd9d1a99640b0b8967ce066269b 100644 (file)
@@ -78,16 +78,26 @@ static void dump(const char *name, uint8_t *data, unsigned data_size)
        fprintf(stderr, "\n");
 }
 
+static void terminate(void)
+{
+       int status = 0;
+
+       kill(child, SIGTERM);
+       wait(&status);
+       exit(1);
+}
+
 static void client(int fd)
 {
        gnutls_session_t session;
        int ret;
-       gnutls_datum_t proto;
        gnutls_anon_client_credentials_t anoncred;
        gnutls_datum_t mac_key, iv, cipher_key;
        gnutls_datum_t read_mac_key, read_iv, read_cipher_key;
-       unsigned char seq_number[8];
+       unsigned char rseq_number[8];
+       unsigned char wseq_number[8];
        unsigned char key_material[512], *p;
+       unsigned i;
        unsigned block_size, hash_size, key_size, iv_size;
        const char *err;
        /* Need to enable anonymous KX specifically. */
@@ -130,7 +140,7 @@ static void client(int fd)
 
        if (ret < 0) {
                fail("client: Handshake failed: %s\n", strerror(ret));
-               exit(1);
+               terminate();
        } else {
                if (debug)
                        success("client: Handshake was completed\n");
@@ -144,13 +154,13 @@ static void client(int fd)
        ret = gnutls_cipher_get(session);
        if (ret != GNUTLS_CIPHER_AES_128_CBC) {
                fprintf(stderr, "negotiated unexpected cipher: %s\n", gnutls_cipher_get_name(ret));
-               exit(1);
+               terminate();
        }
 
        ret = gnutls_mac_get(session);
        if (ret != GNUTLS_MAC_SHA1) {
                fprintf(stderr, "negotiated unexpected mac: %s\n", gnutls_mac_get_name(ret));
-               exit(1);
+               terminate();
        }
 
        iv_size = 16;
@@ -163,29 +173,42 @@ static void client(int fd)
        if (ret < 0) {
                fprintf(stderr, "error in %d\n", __LINE__);
                gnutls_perror(ret);
-               exit(1);
+               terminate();
        }
        p = key_material;
 
-       ret = gnutls_record_get_state(session, 0, &mac_key, &iv, &cipher_key, seq_number);
+       /* check whether the key material matches our calculations */
+       ret = gnutls_record_get_state(session, 0, &mac_key, &iv, &cipher_key, wseq_number);
        if (ret < 0) {
                fprintf(stderr, "error in %d\n", __LINE__);
                gnutls_perror(ret);
-               exit(1);
+               terminate();
+       }
+
+       if (memcmp(wseq_number, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) != 0) {
+               dump("wseq:", wseq_number, 8);
+               fprintf(stderr, "error in %d\n", __LINE__);
+               terminate();
        }
 
-       ret = gnutls_record_get_state(session, 1, &read_mac_key, &read_iv, &read_cipher_key, seq_number);
+       ret = gnutls_record_get_state(session, 1, &read_mac_key, &read_iv, &read_cipher_key, rseq_number);
        if (ret < 0) {
                fprintf(stderr, "error in %d\n", __LINE__);
                gnutls_perror(ret);
-               exit(1);
+               terminate();
+       }
+
+       if (memcmp(rseq_number, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) != 0) {
+               dump("rseq:", rseq_number, 8);
+               fprintf(stderr, "error in %d\n", __LINE__);
+               terminate();
        }
 
        if (hash_size != mac_key.size || memcmp(p, mac_key.data, hash_size) != 0) {
                dump("MAC:", mac_key.data, mac_key.size);
                dump("Block:", key_material, block_size);
                fprintf(stderr, "error in %d\n", __LINE__);
-               exit(1);
+               terminate();
        }
        p+= hash_size;
 
@@ -193,42 +216,66 @@ static void client(int fd)
                dump("MAC:", read_mac_key.data, read_mac_key.size);
                dump("Block:", key_material, block_size);
                fprintf(stderr, "error in %d\n", __LINE__);
-               exit(1);
+               terminate();
        }
        p+= hash_size;
 
        if (key_size != cipher_key.size || memcmp(p, cipher_key.data, key_size) != 0) {
                fprintf(stderr, "error in %d\n", __LINE__);
-               exit(1);
+               terminate();
        }
        p+= key_size;
 
        if (key_size != read_cipher_key.size || memcmp(p, read_cipher_key.data, key_size) != 0) {
                fprintf(stderr, "error in %d\n", __LINE__);
-               exit(1);
+               terminate();
        }
        p+= key_size;
 
        if (iv_size != iv.size || memcmp(p, iv.data, iv_size) != 0) {
                fprintf(stderr, "error in %d\n", __LINE__);
-               exit(1);
+               terminate();
        }
        p+=iv_size;
 
        if (iv_size != read_iv.size || memcmp(p, read_iv.data, iv_size) != 0) {
                fprintf(stderr, "error in %d\n", __LINE__);
-               exit(1);
+               terminate();
        }
 
-       /* check whether the key material matches our calculations */
-       
+       /* check sequence numbers */
+       for (i=0;i<5;i++) {
+               ret = gnutls_record_send(session, "hello", 5);
+               if (ret < 0) {
+                       fail("gnutls_record_send: %s\n", gnutls_strerror(ret));
+               }
+       }
 
-       if (debug) {
-               fprintf(stderr, "selected protocol: %.*s\n",
-                       (int) proto.size, proto.data);
+       ret = gnutls_record_get_state(session, 0, NULL, NULL, NULL, wseq_number);
+       if (ret < 0) {
+               fprintf(stderr, "error in %d\n", __LINE__);
+               gnutls_perror(ret);
+               terminate();
        }
 
+       if (memcmp(wseq_number, "\x00\x00\x00\x00\x00\x00\x00\x06", 8) != 0) {
+               dump("wseq:", wseq_number, 8);
+               fprintf(stderr, "error in %d\n", __LINE__);
+               terminate();
+       }
+
+       ret = gnutls_record_get_state(session, 1, NULL, NULL, NULL, rseq_number);
+       if (ret < 0) {
+               fprintf(stderr, "error in %d\n", __LINE__);
+               gnutls_perror(ret);
+               terminate();
+       }
 
+       if (memcmp(rseq_number, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) != 0) {
+               dump("wseq:", wseq_number, 8);
+               fprintf(stderr, "error in %d\n", __LINE__);
+               terminate();
+       }
        gnutls_bye(session, GNUTLS_SHUT_WR);
 
        close(fd);
@@ -240,21 +287,13 @@ static void client(int fd)
        gnutls_global_deinit();
 }
 
-static void terminate(void)
-{
-       int status = 0;
-
-       kill(child, SIGTERM);
-       wait(&status);
-       exit(1);
-}
-
 static void server(int fd)
 {
        int ret;
        gnutls_session_t session;
        gnutls_anon_server_credentials_t anoncred;
        gnutls_dh_params_t dh_params;
+       char buf[128];
        const gnutls_datum_t p3 =
            { (unsigned char *) pkcs3, strlen(pkcs3) };
 
@@ -308,6 +347,14 @@ static void server(int fd)
                        gnutls_protocol_get_name
                        (gnutls_protocol_get_version(session)));
 
+       do {
+               ret = gnutls_record_recv(session, buf, sizeof(buf));
+       } while(ret > 0);
+
+       if (ret < 0) {
+               fail("error: %s\n", gnutls_strerror(ret));
+       }
+
        /* do not wait for the peer to close the connection.
         */
        gnutls_bye(session, GNUTLS_SHUT_WR);