/** * gnutls_x509_crl_set_number - Set the CRL's number extension * @crl: a CRL of type #gnutls_x509_crl_t * @nr: The CRL number * @nr_size: Holds the size of the nr field. * * This function will set the CRL's number extension. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. * * Since: 2.8.0 **/ int gnutls_x509_crl_set_number (gnutls_x509_crl_t crl, const void *nr, size_t nr_size) { int result; gnutls_datum_t old_id, der_data; unsigned int critical; if (crl == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* Check if the extension already exists. */ result = _gnutls_x509_crl_get_extension (crl, "2.5.29.20", 0, &old_id, &critical); if (result >= 0) _gnutls_free_datum (&old_id); if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* generate the extension. */ result = _gnutls_x509_ext_gen_number (nr, nr_size, &der_data); if (result < 0) { gnutls_assert (); return result; } result = _gnutls_x509_crl_set_extension (crl, "2.5.29.20", &der_data, 0); _gnutls_free_datum (&der_data); if (result < 0) { gnutls_assert (); return result; } crl->use_extensions = 1; return 0; }
/** * gnutls_pkcs11_copy_x509_crt2: * @token_url: A PKCS #11 URL specifying a token * @crt: The certificate to copy * @label: The name to be used for the stored data * @cid: The CKA_ID to set for the object -if NULL, the ID will be derived from the public key * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_* * * This function will copy a certificate into a PKCS #11 token specified by * a URL. Valid flags to mark the certificate: %GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED, * %GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE, %GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE, * %GNUTLS_PKCS11_OBJ_FLAG_MARK_CA, %GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.4.0 **/ int gnutls_pkcs11_copy_x509_crt2(const char *token_url, gnutls_x509_crt_t crt, const char *label, const gnutls_datum_t *cid, unsigned int flags) { int ret; struct p11_kit_uri *info = NULL; ck_rv_t rv; size_t der_size, id_size, serial_size; gnutls_datum_t serial_der = {NULL, 0}; uint8_t *der = NULL; uint8_t serial[128]; uint8_t id[20]; struct ck_attribute a[MAX_ASIZE]; ck_object_class_t class = CKO_CERTIFICATE; ck_certificate_type_t type = CKC_X_509; ck_object_handle_t ctx; unsigned a_val; struct pkcs11_session_info sinfo; PKCS11_CHECK_INIT; ret = pkcs11_url_to_info(token_url, &info, 0); if (ret < 0) { gnutls_assert(); return ret; } ret = pkcs11_open_session(&sinfo, NULL, info, SESSION_WRITE | pkcs11_obj_flags_to_int(flags)); p11_kit_uri_free(info); if (ret < 0) { gnutls_assert(); return ret; } der_size = 0; ret = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, NULL, &der_size); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_assert(); goto cleanup; } der = gnutls_malloc(der_size); if (der == NULL) { gnutls_assert(); ret = GNUTLS_E_MEMORY_ERROR; goto cleanup; } ret = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, der, &der_size); if (ret < 0) { gnutls_assert(); goto cleanup; } a[0].type = CKA_CLASS; a[0].value = &class; a[0].value_len = sizeof(class); a[1].type = CKA_ID; if (cid == NULL || cid->size == 0) { id_size = sizeof(id); ret = gnutls_x509_crt_get_subject_key_id(crt, id, &id_size, NULL); if (ret < 0) { id_size = sizeof(id); ret = gnutls_x509_crt_get_key_id(crt, 0, id, &id_size); if (ret < 0) { gnutls_assert(); goto cleanup; } } a[1].value = id; a[1].value_len = id_size; } else { a[1].value = cid->data; a[1].value_len = cid->size; } a[2].type = CKA_VALUE; a[2].value = der; a[2].value_len = der_size; a[3].type = CKA_TOKEN; a[3].value = (void *) &tval; a[3].value_len = sizeof(tval); a[4].type = CKA_CERTIFICATE_TYPE; a[4].value = &type; a[4].value_len = sizeof(type); /* FIXME: copy key usage flags */ a_val = 5; a[a_val].type = CKA_SUBJECT; a[a_val].value = crt->raw_dn.data; a[a_val].value_len = crt->raw_dn.size; a_val++; a[a_val].type = CKA_ISSUER; a[a_val].value = crt->raw_issuer_dn.data; a[a_val].value_len = crt->raw_issuer_dn.size; a_val++; serial_size = sizeof(serial); if (gnutls_x509_crt_get_serial(crt, serial, &serial_size) >= 0) { ret = _gnutls_x509_ext_gen_number(serial, serial_size, &serial_der); if (ret >= 0) { a[a_val].type = CKA_SERIAL_NUMBER; a[a_val].value = (void *) serial_der.data; a[a_val].value_len = serial_der.size; a_val++; } } if (label) { a[a_val].type = CKA_LABEL; a[a_val].value = (void *) label; a[a_val].value_len = strlen(label); a_val++; } mark_flags(flags, a, &a_val, sinfo.trusted); rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx); if (rv != CKR_OK) { gnutls_assert(); _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv)); ret = pkcs11_rv_to_err(rv); goto cleanup; } /* generated! */ ret = 0; cleanup: gnutls_free(der); gnutls_free(serial_der.data); pkcs11_close_session(&sinfo); return ret; }