/* If OPTIONAL fields have not been initialized then * disable them. */ static void disable_optional_stuff(gnutls_x509_crt_t cert) { asn1_data_node_st n; asn1_node node; unsigned remove_subject_unique_id = 1; unsigned remove_issuer_unique_id = 1; node = asn1_find_node(cert->cert, "tbsCertificate.issuerUniqueID"); if (node) { if (asn1_read_node_value(node, &n) == ASN1_SUCCESS && n.value_len != 0) remove_issuer_unique_id = 0; } node = asn1_find_node(cert->cert, "tbsCertificate.subjectUniqueID"); if (node) { if (asn1_read_node_value(node, &n) == ASN1_SUCCESS && n.value_len != 0) remove_subject_unique_id = 0; } if (remove_issuer_unique_id) asn1_write_value(cert->cert, "tbsCertificate.issuerUniqueID", NULL, 0); if (remove_subject_unique_id) asn1_write_value(cert->cert, "tbsCertificate.subjectUniqueID", NULL, 0); if (cert->use_extensions == 0) { _gnutls_debug_log("Disabling X.509 extensions.\n"); asn1_write_value(cert->cert, "tbsCertificate.extensions", NULL, 0); } return; }
/** * gnutls_x509_dn_get_rdn_ava: * @dn: a pointer to DN * @irdn: index of RDN * @iava: index of AVA. * @ava: Pointer to structure which will hold output information. * * Get pointers to data within the DN. The format of the @ava structure * is shown below. * * struct gnutls_x509_ava_st { * gnutls_datum_t oid; * gnutls_datum_t value; * unsigned long value_tag; * }; * * The X.509 distinguished name is a sequence of sequences of strings * and this is what the @irdn and @iava indexes model. * * Note that @ava will contain pointers into the @dn structure which * in turns points to the original certificate. Thus you should not * modify any data or deallocate any of those. * * This is a low-level function that requires the caller to do the * value conversions when necessary (e.g. from UCS-2). * * Returns: Returns 0 on success, or an error code. **/ int gnutls_x509_dn_get_rdn_ava(gnutls_x509_dn_t dn, int irdn, int iava, gnutls_x509_ava_st * ava) { ASN1_TYPE rdn, elem; ASN1_DATA_NODE vnode; long len; int lenlen, remlen, ret; char rbuf[MAX_NAME_SIZE]; unsigned char cls; const unsigned char *ptr; iava++; irdn++; /* 0->1, 1->2 etc */ snprintf(rbuf, sizeof(rbuf), "rdnSequence.?%d.?%d", irdn, iava); rdn = asn1_find_node(dn->asn, rbuf); if (!rdn) { gnutls_assert(); return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND; } snprintf(rbuf, sizeof(rbuf), "?%d.type", iava); elem = asn1_find_node(rdn, rbuf); if (!elem) { gnutls_assert(); return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND; } ret = asn1_read_node_value(elem, &vnode); if (ret != ASN1_SUCCESS) { gnutls_assert(); return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND; } ava->oid.data = (void *) vnode.value; ava->oid.size = vnode.value_len; snprintf(rbuf, sizeof(rbuf), "?%d.value", iava); elem = asn1_find_node(rdn, rbuf); if (!elem) { gnutls_assert(); return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND; } ret = asn1_read_node_value(elem, &vnode); if (ret != ASN1_SUCCESS) { gnutls_assert(); return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND; } /* The value still has the previous tag's length bytes, plus the * current value's tag and length bytes. Decode them. */ ptr = vnode.value; remlen = vnode.value_len; len = asn1_get_length_der(ptr, remlen, &lenlen); if (len < 0) { gnutls_assert(); return GNUTLS_E_ASN1_DER_ERROR; } ptr += lenlen; remlen -= lenlen; ret = asn1_get_tag_der(ptr, remlen, &cls, &lenlen, &ava->value_tag); if (ret) { gnutls_assert(); return _gnutls_asn2err(ret); } ptr += lenlen; remlen -= lenlen; { signed long tmp; tmp = asn1_get_length_der(ptr, remlen, &lenlen); if (tmp < 0) { gnutls_assert(); return GNUTLS_E_ASN1_DER_ERROR; } ava->value.size = tmp; } ava->value.data = (void *) (ptr + lenlen); return 0; }