123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /*
- * QEMU TLS Cipher Suites
- *
- * Copyright (c) 2018-2020 Red Hat, Inc.
- *
- * Author: Philippe Mathieu-Daudé <philmd@redhat.com>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
- #include "qemu/osdep.h"
- #include "qapi/error.h"
- #include "qom/object_interfaces.h"
- #include "crypto/tlscreds.h"
- #include "crypto/tls-cipher-suites.h"
- #include "hw/nvram/fw_cfg.h"
- #include "tlscredspriv.h"
- #include "trace.h"
- struct QCryptoTLSCipherSuites {
- /* <private> */
- QCryptoTLSCreds parent_obj;
- /* <public> */
- };
- /*
- * IANA registered TLS ciphers:
- * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4
- */
- typedef struct {
- uint8_t data[2];
- } QEMU_PACKED IANA_TLS_CIPHER;
- GByteArray *qcrypto_tls_cipher_suites_get_data(QCryptoTLSCipherSuites *obj,
- Error **errp)
- {
- QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
- gnutls_priority_t pcache;
- GByteArray *byte_array;
- const char *err;
- size_t i;
- int ret;
- trace_qcrypto_tls_cipher_suite_priority(creds->priority);
- ret = gnutls_priority_init(&pcache, creds->priority, &err);
- if (ret < 0) {
- error_setg(errp, "Syntax error using priority '%s': %s",
- creds->priority, gnutls_strerror(ret));
- return NULL;
- }
- byte_array = g_byte_array_new();
- for (i = 0;; i++) {
- unsigned idx;
- const char *name;
- IANA_TLS_CIPHER cipher;
- gnutls_protocol_t protocol;
- const char *version;
- ret = gnutls_priority_get_cipher_suite_index(pcache, i, &idx);
- if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
- break;
- }
- if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) {
- continue;
- }
- name = gnutls_cipher_suite_info(idx, (unsigned char *)&cipher,
- NULL, NULL, NULL, &protocol);
- if (name == NULL) {
- continue;
- }
- version = gnutls_protocol_get_name(protocol);
- g_byte_array_append(byte_array, cipher.data, 2);
- trace_qcrypto_tls_cipher_suite_info(cipher.data[0],
- cipher.data[1],
- version, name);
- }
- trace_qcrypto_tls_cipher_suite_count(byte_array->len);
- gnutls_priority_deinit(pcache);
- return byte_array;
- }
- static void qcrypto_tls_cipher_suites_complete(UserCreatable *uc,
- Error **errp)
- {
- QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(uc);
- if (!creds->priority) {
- error_setg(errp, "'priority' property is not set");
- return;
- }
- }
- static GByteArray *qcrypto_tls_cipher_suites_fw_cfg_gen_data(Object *obj,
- Error **errp)
- {
- return qcrypto_tls_cipher_suites_get_data(QCRYPTO_TLS_CIPHER_SUITES(obj),
- errp);
- }
- static void qcrypto_tls_cipher_suites_class_init(ObjectClass *oc, void *data)
- {
- UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
- FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(oc);
- ucc->complete = qcrypto_tls_cipher_suites_complete;
- fwgc->get_data = qcrypto_tls_cipher_suites_fw_cfg_gen_data;
- }
- static const TypeInfo qcrypto_tls_cipher_suites_info = {
- .parent = TYPE_QCRYPTO_TLS_CREDS,
- .name = TYPE_QCRYPTO_TLS_CIPHER_SUITES,
- .instance_size = sizeof(QCryptoTLSCipherSuites),
- .class_size = sizeof(QCryptoTLSCredsClass),
- .class_init = qcrypto_tls_cipher_suites_class_init,
- .interfaces = (InterfaceInfo[]) {
- { TYPE_USER_CREATABLE },
- { TYPE_FW_CFG_DATA_GENERATOR_INTERFACE },
- { }
- }
- };
- static void qcrypto_tls_cipher_suites_register_types(void)
- {
- type_register_static(&qcrypto_tls_cipher_suites_info);
- }
- type_init(qcrypto_tls_cipher_suites_register_types);
|