/** * gnutls_x509_crt_set_key_usage: * @crt: a certificate of type #gnutls_x509_crt_t * @usage: an ORed sequence of the GNUTLS_KEY_* elements. * * This function will set the keyUsage certificate extension. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crt_set_key_usage(gnutls_x509_crt_t crt, unsigned int usage) { int result; gnutls_datum_t der_data; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } /* generate the extension. */ result = gnutls_x509_ext_export_key_usage(usage, &der_data); if (result < 0) { gnutls_assert(); return result; } result = _gnutls_x509_crt_set_extension(crt, "2.5.29.15", &der_data, 1); _gnutls_free_datum(&der_data); if (result < 0) { gnutls_assert(); return result; } crt->use_extensions = 1; return 0; }
/** * gnutls_x509_crt_set_private_key_usage_period: * @crt: a certificate of type #gnutls_x509_crt_t * @activation: The activation time * @expiration: The expiration time * * This function will set the private key usage period extension (2.5.29.16). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crt_set_private_key_usage_period(gnutls_x509_crt_t crt, time_t activation, time_t expiration) { int result; gnutls_datum_t der_data; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } result = gnutls_x509_ext_export_private_key_usage_period(activation, expiration, &der_data); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_crt_set_extension(crt, "2.5.29.16", &der_data, 0); _gnutls_free_datum(&der_data); crt->use_extensions = 1; cleanup: return result; }
/** * gnutls_x509_crt_set_extension_by_oid: * @crt: a certificate of type #gnutls_x509_crt_t * @oid: holds an Object Identified in null terminated string * @buf: a pointer to a DER encoded data * @sizeof_buf: holds the size of @buf * @critical: should be non-zero if the extension is to be marked as critical * * This function will set an the extension, by the specified OID, in * the certificate. The extension data should be binary data DER * encoded. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crt_set_extension_by_oid(gnutls_x509_crt_t crt, const char *oid, const void *buf, size_t sizeof_buf, unsigned int critical) { int result; gnutls_datum_t der_data; der_data.data = (void *) buf; der_data.size = sizeof_buf; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } result = _gnutls_x509_crt_set_extension(crt, oid, &der_data, critical); if (result < 0) { gnutls_assert(); return result; } crt->use_extensions = 1; return 0; }
/** * gnutls_x509_crt_set_basic_constraints: * @crt: a certificate of type #gnutls_x509_crt_t * @ca: true(1) or false(0). Depending on the Certificate authority status. * @pathLenConstraint: non-negative error codes indicate maximum length of path, * and negative error codes indicate that the pathLenConstraints field should * not be present. * * This function will set the basicConstraints certificate extension. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crt_set_basic_constraints(gnutls_x509_crt_t crt, unsigned int ca, int pathLenConstraint) { int result; gnutls_datum_t der_data; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } /* generate the extension. */ result = gnutls_x509_ext_export_basic_constraints(ca, pathLenConstraint, &der_data); if (result < 0) { gnutls_assert(); return result; } result = _gnutls_x509_crt_set_extension(crt, "2.5.29.19", &der_data, 1); _gnutls_free_datum(&der_data); if (result < 0) { gnutls_assert(); return result; } crt->use_extensions = 1; return 0; }
/** * gnutls_x509_crt_set_crl_dist_points2: * @crt: a certificate of type #gnutls_x509_crt_t * @type: is one of the gnutls_x509_subject_alt_name_t enumerations * @data: The data to be set * @data_size: The data size * @reason_flags: revocation reasons * * This function will set the CRL distribution points certificate extension. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.6.0 **/ int gnutls_x509_crt_set_crl_dist_points2(gnutls_x509_crt_t crt, gnutls_x509_subject_alt_name_t type, const void *data, unsigned int data_size, unsigned int reason_flags) { int result; gnutls_datum_t der_data = { NULL, 0 }; gnutls_datum_t oldname = { NULL, 0 }; unsigned int critical; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } /* Check if the extension already exists. */ result = _gnutls_x509_crt_get_extension(crt, "2.5.29.31", 0, &oldname, &critical); _gnutls_free_datum(&oldname); if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } /* generate the extension. */ result = _gnutls_x509_ext_gen_crl_dist_points(type, data, data_size, reason_flags, &der_data); if (result < 0) { gnutls_assert(); return result; } result = _gnutls_x509_crt_set_extension(crt, "2.5.29.31", &der_data, 0); _gnutls_free_datum(&der_data); if (result < 0) { gnutls_assert(); return result; } crt->use_extensions = 1; return 0; }
/** * gnutls_x509_crt_set_subject_key_id: * @cert: a certificate of type #gnutls_x509_crt_t * @id: The key ID * @id_size: Holds the size of the subject key ID field. * * This function will set the X.509 certificate's subject key ID * extension. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crt_set_subject_key_id(gnutls_x509_crt_t cert, const void *id, size_t id_size) { int result; gnutls_datum_t old_id, der_data; gnutls_datum_t d_id; unsigned int critical; if (cert == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } /* Check if the extension already exists. */ result = _gnutls_x509_crt_get_extension(cert, "2.5.29.14", 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. */ d_id.data = (void*)id; d_id.size = id_size; result = gnutls_x509_ext_export_subject_key_id(&d_id, &der_data); if (result < 0) { gnutls_assert(); return result; } result = _gnutls_x509_crt_set_extension(cert, "2.5.29.14", &der_data, 0); _gnutls_free_datum(&der_data); if (result < 0) { gnutls_assert(); return result; } cert->use_extensions = 1; return 0; }
/** * gnutls_x509_crt_set_private_key_usage_period: * @crt: a certificate of type #gnutls_x509_crt_t * @activation: The activation time * @expiration: The expiration time * * This function will set the private key usage period extension (2.5.29.16). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crt_set_private_key_usage_period(gnutls_x509_crt_t crt, time_t activation, time_t expiration) { int result; gnutls_datum_t der_data; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.PrivateKeyUsagePeriod", &c2); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = _gnutls_x509_set_time(c2, "notBefore", activation, 1); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_set_time(c2, "notAfter", expiration, 1); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_der_encode(c2, "", &der_data, 0); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_crt_set_extension(crt, "2.5.29.16", &der_data, 0); _gnutls_free_datum(&der_data); crt->use_extensions = 1; cleanup: asn1_delete_structure(&c2); return result; }
static int override_ext(gnutls_x509_crt_t crt, gnutls_datum_t *ext) { gnutls_x509_ext_st parsed; int ret; ret = _gnutls_x509_decode_ext(ext, &parsed); if (ret < 0) return gnutls_assert_val(ret); /* set the new extension */ ret = _gnutls_x509_crt_set_extension(crt, parsed.oid, &parsed.data, parsed.critical); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = 0; cleanup: gnutls_x509_ext_deinit(&parsed); return ret; }
/** * gnutls_x509_crt_set_proxy: * @crt: a certificate of type #gnutls_x509_crt_t * @pathLenConstraint: non-negative error codes indicate maximum length of path, * and negative error codes indicate that the pathLenConstraints field should * not be present. * @policyLanguage: OID describing the language of @policy. * @policy: uint8_t byte array with policy language, can be %NULL * @sizeof_policy: size of @policy. * * This function will set the proxyCertInfo extension. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crt_set_proxy(gnutls_x509_crt_t crt, int pathLenConstraint, const char *policyLanguage, const char *policy, size_t sizeof_policy) { int result; gnutls_datum_t der_data; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } /* generate the extension. */ result = gnutls_x509_ext_export_proxy(pathLenConstraint, policyLanguage, policy, sizeof_policy, &der_data); if (result < 0) { gnutls_assert(); return result; } result = _gnutls_x509_crt_set_extension(crt, "1.3.6.1.5.5.7.1.14", &der_data, 1); _gnutls_free_datum(&der_data); if (result < 0) { gnutls_assert(); return result; } crt->use_extensions = 1; return 0; }
/** * gnutls_x509_crt_cpy_crl_dist_points: * @dst: a certificate of type #gnutls_x509_crt_t * @src: the certificate where the dist points will be copied from * * This function will copy the CRL distribution points certificate * extension, from the source to the destination certificate. * This may be useful to copy from a CA certificate to issued ones. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crt_cpy_crl_dist_points(gnutls_x509_crt_t dst, gnutls_x509_crt_t src) { int result; gnutls_datum_t der_data; unsigned int critical; if (dst == NULL || src == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } /* Check if the extension already exists. */ result = _gnutls_x509_crt_get_extension(src, "2.5.29.31", 0, &der_data, &critical); if (result < 0) { gnutls_assert(); return result; } result = _gnutls_x509_crt_set_extension(dst, "2.5.29.31", &der_data, critical); _gnutls_free_datum(&der_data); if (result < 0) { gnutls_assert(); return result; } dst->use_extensions = 1; return 0; }
/** * gnutls_x509_crt_set_crl_dist_points2: * @crt: a certificate of type #gnutls_x509_crt_t * @type: is one of the gnutls_x509_subject_alt_name_t enumerations * @data: The data to be set * @data_size: The data size * @reason_flags: revocation reasons * * This function will set the CRL distribution points certificate extension. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.6.0 **/ int gnutls_x509_crt_set_crl_dist_points2(gnutls_x509_crt_t crt, gnutls_x509_subject_alt_name_t type, const void *data, unsigned int data_size, unsigned int reason_flags) { int ret; gnutls_datum_t der_data = { NULL, 0 }; gnutls_datum_t old_der = { NULL, 0 }; unsigned int critical; gnutls_x509_crl_dist_points_t cdp = NULL; gnutls_datum_t san; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } ret = gnutls_x509_crl_dist_points_init(&cdp); if (ret < 0) return gnutls_assert_val(ret); /* Check if the extension already exists. */ ret = _gnutls_x509_crt_get_extension(crt, "2.5.29.31", 0, &old_der, &critical); if (ret >= 0 && old_der.data != NULL) { ret = gnutls_x509_ext_import_crl_dist_points(&old_der, cdp, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } } san.data = (void*)data; san.size = data_size; ret = gnutls_x509_crl_dist_points_set(cdp, type, &san, reason_flags); if (ret < 0) { gnutls_assert(); goto cleanup; } /* generate the extension. */ ret = gnutls_x509_ext_export_crl_dist_points(cdp, &der_data); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_crt_set_extension(crt, "2.5.29.31", &der_data, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } crt->use_extensions = 1; ret = 0; cleanup: _gnutls_free_datum(&der_data); _gnutls_free_datum(&old_der); if (cdp != NULL) gnutls_x509_crl_dist_points_deinit(cdp); return ret; }
/** * gnutls_x509_crt_set_issuer_alt_name: * @crt: a certificate of type #gnutls_x509_crt_t * @type: is one of the gnutls_x509_subject_alt_name_t enumerations * @data: The data to be set * @data_size: The size of data to be set * @flags: GNUTLS_FSAN_SET to clear previous data or GNUTLS_FSAN_APPEND to append. * * This function will set the issuer alternative name certificate * extension. It can set the same types as gnutls_x509_crt_set_subject_alt_name(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.3.0 **/ int gnutls_x509_crt_set_issuer_alt_name(gnutls_x509_crt_t crt, gnutls_x509_subject_alt_name_t type, const void *data, unsigned int data_size, unsigned int flags) { int result; gnutls_datum_t der_data = { NULL, 0 }; gnutls_datum_t prev_der_data = { NULL, 0 }; unsigned int critical = 0; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } /* Check if the extension already exists. */ if (flags == GNUTLS_FSAN_APPEND) { result = _gnutls_x509_crt_get_extension(crt, "2.5.29.18", 0, &prev_der_data, &critical); if (result < 0 && result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { gnutls_assert(); return result; } } /* generate the extension. */ result = _gnutls_x509_ext_gen_subject_alt_name(type, data, data_size, &prev_der_data, &der_data); if (flags == GNUTLS_FSAN_APPEND) _gnutls_free_datum(&prev_der_data); if (result < 0) { gnutls_assert(); goto finish; } result = _gnutls_x509_crt_set_extension(crt, "2.5.29.18", &der_data, critical); _gnutls_free_datum(&der_data); if (result < 0) { gnutls_assert(); return result; } crt->use_extensions = 1; return 0; finish: _gnutls_free_datum(&prev_der_data); return result; }
/** * gnutls_x509_crt_set_crq_extensions: * @crt: a certificate of type #gnutls_x509_crt_t * @crq: holds a certificate request * * This function will set extensions from the given request to the * certificate. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.8.0 **/ int gnutls_x509_crt_set_crq_extensions(gnutls_x509_crt_t crt, gnutls_x509_crq_t crq) { size_t i; if (crt == NULL || crq == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } for (i = 0;; i++) { int result; char oid[MAX_OID_SIZE]; size_t oid_size; uint8_t *extensions; size_t extensions_size; unsigned int critical; gnutls_datum_t ext; oid_size = sizeof(oid); result = gnutls_x509_crq_get_extension_info(crq, i, oid, &oid_size, &critical); if (result < 0) { if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) break; gnutls_assert(); return result; } extensions_size = 0; result = gnutls_x509_crq_get_extension_data(crq, i, NULL, &extensions_size); if (result < 0) { gnutls_assert(); return result; } extensions = gnutls_malloc(extensions_size); if (extensions == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } result = gnutls_x509_crq_get_extension_data(crq, i, extensions, &extensions_size); if (result < 0) { gnutls_assert(); gnutls_free(extensions); return result; } ext.data = extensions; ext.size = extensions_size; result = _gnutls_x509_crt_set_extension(crt, oid, &ext, critical); gnutls_free(extensions); if (result < 0) { gnutls_assert(); return result; } } if (i > 0) crt->use_extensions = 1; return 0; }
/** * gnutls_x509_crt_set_policy: * @crt: should contain a #gnutls_x509_crt_t structure * @policy: A pointer to a policy structure. * @critical: use non-zero if the extension is marked as critical * * This function will set the certificate policy extension (2.5.29.32). * Multiple calls to this function append a new policy. * * Note the maximum text size for the qualifier %GNUTLS_X509_QUALIFIER_NOTICE * is 200 characters. This function will fail with %GNUTLS_E_INVALID_REQUEST * if this is exceeded. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.1.5 **/ int gnutls_x509_crt_set_policy(gnutls_x509_crt_t crt, const struct gnutls_x509_policy_st *policy, unsigned int critical) { int ret; gnutls_datum_t der_data = {NULL, 0}, prev_der_data = { NULL, 0 }; gnutls_x509_policies_t policies = NULL; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } ret = gnutls_x509_policies_init(&policies); if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_x509_crt_get_extension(crt, "2.5.29.32", 0, &prev_der_data, NULL); if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { gnutls_assert(); goto cleanup; } if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { ret = gnutls_x509_ext_import_policies(&prev_der_data, policies, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } } ret = gnutls_x509_policies_set(policies, policy); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = gnutls_x509_ext_export_policies(policies, &der_data); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_crt_set_extension(crt, "2.5.29.32", &der_data, 0); crt->use_extensions = 1; cleanup: if (policies != NULL) gnutls_x509_policies_deinit(policies); _gnutls_free_datum(&prev_der_data); _gnutls_free_datum(&der_data); return ret; }
/** * gnutls_x509_crt_set_authority_info_access: * @crt: Holds the certificate * @what: what data to get, a #gnutls_info_access_what_t type. * @data: output data to be freed with gnutls_free(). * * This function sets the Authority Information Access (AIA) * extension, see RFC 5280 section 4.2.2.1 for more information. * * The type of data stored in @data is specified via @what which * should be #gnutls_info_access_what_t values. * * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI. * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers * URI. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.0 **/ int gnutls_x509_crt_set_authority_info_access(gnutls_x509_crt_t crt, int what, gnutls_datum_t * data) { int ret; gnutls_datum_t der = { NULL, 0 }; gnutls_datum_t new_der = { NULL, 0 }; gnutls_x509_aia_t aia_ctx = NULL; const char *oid; unsigned int c; if (crt == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ret = gnutls_x509_aia_init(&aia_ctx); if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &der, &c); if (ret >= 0) { /* decode it */ ret = gnutls_x509_ext_import_aia(&der, aia_ctx, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } } if (what == GNUTLS_IA_OCSP_URI) oid = GNUTLS_OID_AD_OCSP; else if (what == GNUTLS_IA_CAISSUERS_URI) oid = GNUTLS_OID_AD_CAISSUERS; else return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ret = gnutls_x509_aia_set(aia_ctx, oid, GNUTLS_SAN_URI, data); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = gnutls_x509_ext_export_aia(aia_ctx, &new_der); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_crt_set_extension(crt, GNUTLS_OID_AIA, &new_der, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } crt->use_extensions = 1; cleanup: if (aia_ctx != NULL) gnutls_x509_aia_deinit(aia_ctx); _gnutls_free_datum(&new_der); _gnutls_free_datum(&der); return ret; }
/** * gnutls_x509_crt_set_key_purpose_oid: * @cert: a certificate of type #gnutls_x509_crt_t * @oid: a pointer to a null terminated string that holds the OID * @critical: Whether this extension will be critical or not * * This function will set the key purpose OIDs of the Certificate. * These are stored in the Extended Key Usage extension (2.5.29.37) * See the GNUTLS_KP_* definitions for human readable names. * * Subsequent calls to this function will append OIDs to the OID list. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, * otherwise a negative error code is returned. **/ int gnutls_x509_crt_set_key_purpose_oid(gnutls_x509_crt_t cert, const void *oid, unsigned int critical) { int ret; gnutls_datum_t old_id = {NULL,0}; gnutls_datum_t der = {NULL,0}; gnutls_x509_key_purposes_t p = NULL; if (cert == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } ret = gnutls_x509_key_purpose_init(&p); if (ret < 0) return gnutls_assert_val(ret); /* Check if the extension already exists. */ ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &old_id, NULL); if (ret >= 0) { ret = gnutls_x509_ext_import_key_purposes(&old_id, p, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } } ret = gnutls_x509_key_purpose_set(p, oid); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = gnutls_x509_ext_export_key_purposes(p, &der); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_crt_set_extension(cert, "2.5.29.37", &der, critical); if (ret < 0) { gnutls_assert(); goto cleanup; } cert->use_extensions = 1; ret = 0; cleanup: _gnutls_free_datum(&der); _gnutls_free_datum(&old_id); if (p != NULL) gnutls_x509_key_purpose_deinit(p); return ret; }
/** * gnutls_x509_crt_set_key_purpose_oid: * @cert: a certificate of type #gnutls_x509_crt_t * @oid: a pointer to a null terminated string that holds the OID * @critical: Whether this extension will be critical or not * * This function will set the key purpose OIDs of the Certificate. * These are stored in the Extended Key Usage extension (2.5.29.37) * See the GNUTLS_KP_* definitions for human readable names. * * Subsequent calls to this function will append OIDs to the OID list. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, * otherwise a negative error code is returned. **/ int gnutls_x509_crt_set_key_purpose_oid(gnutls_x509_crt_t cert, const void *oid, unsigned int critical) { int result; gnutls_datum_t old_id, der_data; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; if (cert == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } result = asn1_create_element (_gnutls_get_pkix(), "PKIX1.ExtKeyUsageSyntax", &c2); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } /* Check if the extension already exists. */ result = _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &old_id, NULL); if (result >= 0) { /* decode it. */ result = asn1_der_decoding(&c2, old_id.data, old_id.size, NULL); _gnutls_free_datum(&old_id); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&c2); return _gnutls_asn2err(result); } } /* generate the extension. */ /* 1. create a new element. */ result = asn1_write_value(c2, "", "NEW", 1); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&c2); return _gnutls_asn2err(result); } /* 2. Add the OID. */ result = asn1_write_value(c2, "?LAST", oid, 1); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&c2); return _gnutls_asn2err(result); } result = _gnutls_x509_der_encode(c2, "", &der_data, 0); asn1_delete_structure(&c2); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = _gnutls_x509_crt_set_extension(cert, "2.5.29.37", &der_data, critical); _gnutls_free_datum(&der_data); if (result < 0) { gnutls_assert(); return result; } cert->use_extensions = 1; return 0; }
/** * gnutls_x509_crt_set_authority_info_access: * @crt: Holds the certificate * @what: what data to get, a #gnutls_info_access_what_t type. * @data: output data to be freed with gnutls_free(). * * This function sets the Authority Information Access (AIA) * extension, see RFC 5280 section 4.2.2.1 for more information. * * The type of data stored in @data is specified via @what which * should be #gnutls_info_access_what_t values. * * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI. * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers * URI. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.0 **/ int gnutls_x509_crt_set_authority_info_access(gnutls_x509_crt_t crt, int what, gnutls_datum_t * data) { int ret, result; gnutls_datum_t aia = { NULL, 0 }; gnutls_datum_t der_data = { NULL, 0 }; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; const char *oid; unsigned int c; if (crt == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); oid = what_to_oid(what); if (oid == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.AuthorityInfoAccessSyntax", &c2); if (ret != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(ret); } ret = _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &aia, &c); if (ret >= 0) { /* decode it */ ret = asn1_der_decoding(&c2, aia.data, aia.size, NULL); if (ret != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(ret); goto cleanup; } } /* generate the extension. */ /* 1. create a new element. */ result = asn1_write_value(c2, "", "NEW", 1); if (result != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(result); goto cleanup; } /* 2. Add the OID. */ result = asn1_write_value(c2, "?LAST.accessMethod", oid, 1); if (result != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(result); goto cleanup; } /* accessLocation is a choice */ result = asn1_write_value(c2, "?LAST.accessLocation", "uniformResourceIdentifier", 1); if (result != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(result); goto cleanup; } result = asn1_write_value(c2, "?LAST.accessLocation.uniformResourceIdentifier", data->data, data->size); if (result != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(result); goto cleanup; } ret = _gnutls_x509_der_encode(c2, "", &der_data, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_crt_set_extension(crt, GNUTLS_OID_AIA, &der_data, 0); if (ret < 0) gnutls_assert(); crt->use_extensions = 1; cleanup: _gnutls_free_datum(&der_data); _gnutls_free_datum(&aia); asn1_delete_structure(&c2); return ret; }
/** * gnutls_x509_crt_set_policy: * @cert: should contain a #gnutls_x509_crt_t structure * @policy: A pointer to a policy structure. * @critical: use non-zero if the extension is marked as critical * * This function will set the certificate policy extension (2.5.29.32). * Multiple calls to this function append a new policy. * * Note the maximum text size for the qualifier %GNUTLS_X509_QUALIFIER_NOTICE * is 200 characters. This function will fail with %GNUTLS_E_INVALID_REQUEST * if this is exceeded. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.1.5 **/ int gnutls_x509_crt_set_policy(gnutls_x509_crt_t crt, struct gnutls_x509_policy_st *policy, unsigned int critical) { int result; unsigned i; gnutls_datum_t der_data, tmpd, prev_der_data = { NULL, 0 }; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; const char *oid; if (crt == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } result = _gnutls_x509_crt_get_extension(crt, "2.5.29.32", 0, &prev_der_data, NULL); if (result < 0 && result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { gnutls_assert(); return result; } result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.certificatePolicies", &c2); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } if (prev_der_data.data != NULL) { result = asn1_der_decoding(&c2, prev_der_data.data, prev_der_data.size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } } /* 1. write a new policy */ result = asn1_write_value(c2, "", "NEW", 1); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } /* 2. Add the OID. */ result = asn1_write_value(c2, "?LAST.policyIdentifier", policy->oid, 1); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } for (i = 0; i < MIN(policy->qualifiers, GNUTLS_MAX_QUALIFIERS); i++) { result = asn1_write_value(c2, "?LAST.policyQualifiers", "NEW", 1); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } if (policy->qualifier[i].type == GNUTLS_X509_QUALIFIER_URI) oid = "1.3.6.1.5.5.7.2.1"; else if (policy->qualifier[i].type == GNUTLS_X509_QUALIFIER_NOTICE) oid = "1.3.6.1.5.5.7.2.2"; else { result = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); goto cleanup; } result = asn1_write_value(c2, "?LAST.policyQualifiers.?LAST.policyQualifierId", oid, 1); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } if (policy->qualifier[i].type == GNUTLS_X509_QUALIFIER_URI) { tmpd.data = (void *) policy->qualifier[i].data; tmpd.size = policy->qualifier[i].size; result = _gnutls_x509_write_string(c2, "?LAST.policyQualifiers.?LAST.qualifier", &tmpd, ASN1_ETYPE_IA5_STRING); if (result < 0) { gnutls_assert(); goto cleanup; } } else if (policy->qualifier[i].type == GNUTLS_X509_QUALIFIER_NOTICE) { tmpd.data = (void *) policy->qualifier[i].data; tmpd.size = policy->qualifier[i].size; if (tmpd.size > 200) { gnutls_assert(); result = GNUTLS_E_INVALID_REQUEST; goto cleanup; } result = encode_user_notice(&tmpd, &der_data); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_write_value(c2, "?LAST.policyQualifiers.?LAST.qualifier", &der_data); _gnutls_free_datum(&der_data); if (result < 0) { gnutls_assert(); goto cleanup; } } } result = _gnutls_x509_der_encode(c2, "", &der_data, 0); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_crt_set_extension(crt, "2.5.29.32", &der_data, 0); _gnutls_free_datum(&der_data); crt->use_extensions = 1; cleanup: asn1_delete_structure(&c2); _gnutls_free_datum(&prev_der_data); return result; }