qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

tls-cipher-suites.c (3925B)


      1 /*
      2  * QEMU TLS Cipher Suites
      3  *
      4  * Copyright (c) 2018-2020 Red Hat, Inc.
      5  *
      6  * Author: Philippe Mathieu-Daudé <philmd@redhat.com>
      7  *
      8  * SPDX-License-Identifier: GPL-2.0-or-later
      9  */
     10 
     11 #include "qemu/osdep.h"
     12 #include "qapi/error.h"
     13 #include "qom/object_interfaces.h"
     14 #include "crypto/tlscreds.h"
     15 #include "crypto/tls-cipher-suites.h"
     16 #include "hw/nvram/fw_cfg.h"
     17 #include "tlscredspriv.h"
     18 #include "trace.h"
     19 
     20 struct QCryptoTLSCipherSuites {
     21     /* <private> */
     22     QCryptoTLSCreds parent_obj;
     23     /* <public> */
     24 };
     25 
     26 /*
     27  * IANA registered TLS ciphers:
     28  * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4
     29  */
     30 typedef struct {
     31     uint8_t data[2];
     32 } QEMU_PACKED IANA_TLS_CIPHER;
     33 
     34 GByteArray *qcrypto_tls_cipher_suites_get_data(QCryptoTLSCipherSuites *obj,
     35                                                Error **errp)
     36 {
     37     QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
     38     gnutls_priority_t pcache;
     39     GByteArray *byte_array;
     40     const char *err;
     41     size_t i;
     42     int ret;
     43 
     44     trace_qcrypto_tls_cipher_suite_priority(creds->priority);
     45     ret = gnutls_priority_init(&pcache, creds->priority, &err);
     46     if (ret < 0) {
     47         error_setg(errp, "Syntax error using priority '%s': %s",
     48                    creds->priority, gnutls_strerror(ret));
     49         return NULL;
     50     }
     51 
     52     byte_array = g_byte_array_new();
     53 
     54     for (i = 0;; i++) {
     55         int ret;
     56         unsigned idx;
     57         const char *name;
     58         IANA_TLS_CIPHER cipher;
     59         gnutls_protocol_t protocol;
     60         const char *version;
     61 
     62         ret = gnutls_priority_get_cipher_suite_index(pcache, i, &idx);
     63         if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
     64             break;
     65         }
     66         if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) {
     67             continue;
     68         }
     69 
     70         name = gnutls_cipher_suite_info(idx, (unsigned char *)&cipher,
     71                                         NULL, NULL, NULL, &protocol);
     72         if (name == NULL) {
     73             continue;
     74         }
     75 
     76         version = gnutls_protocol_get_name(protocol);
     77         g_byte_array_append(byte_array, cipher.data, 2);
     78         trace_qcrypto_tls_cipher_suite_info(cipher.data[0],
     79                                             cipher.data[1],
     80                                             version, name);
     81     }
     82     trace_qcrypto_tls_cipher_suite_count(byte_array->len);
     83     gnutls_priority_deinit(pcache);
     84 
     85     return byte_array;
     86 }
     87 
     88 static void qcrypto_tls_cipher_suites_complete(UserCreatable *uc,
     89                                                Error **errp)
     90 {
     91     QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(uc);
     92 
     93     if (!creds->priority) {
     94         error_setg(errp, "'priority' property is not set");
     95         return;
     96     }
     97 }
     98 
     99 static GByteArray *qcrypto_tls_cipher_suites_fw_cfg_gen_data(Object *obj,
    100                                                              Error **errp)
    101 {
    102     return qcrypto_tls_cipher_suites_get_data(QCRYPTO_TLS_CIPHER_SUITES(obj),
    103                                               errp);
    104 }
    105 
    106 static void qcrypto_tls_cipher_suites_class_init(ObjectClass *oc, void *data)
    107 {
    108     UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
    109     FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(oc);
    110 
    111     ucc->complete = qcrypto_tls_cipher_suites_complete;
    112     fwgc->get_data = qcrypto_tls_cipher_suites_fw_cfg_gen_data;
    113 }
    114 
    115 static const TypeInfo qcrypto_tls_cipher_suites_info = {
    116     .parent = TYPE_QCRYPTO_TLS_CREDS,
    117     .name = TYPE_QCRYPTO_TLS_CIPHER_SUITES,
    118     .instance_size = sizeof(QCryptoTLSCipherSuites),
    119     .class_size = sizeof(QCryptoTLSCredsClass),
    120     .class_init = qcrypto_tls_cipher_suites_class_init,
    121     .interfaces = (InterfaceInfo[]) {
    122         { TYPE_USER_CREATABLE },
    123         { TYPE_FW_CFG_DATA_GENERATOR_INTERFACE },
    124         { }
    125     }
    126 };
    127 
    128 static void qcrypto_tls_cipher_suites_register_types(void)
    129 {
    130     type_register_static(&qcrypto_tls_cipher_suites_info);
    131 }
    132 
    133 type_init(qcrypto_tls_cipher_suites_register_types);