static int check_for_decrypted(const gnutls_datum_t *der) { int result; ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY; if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.pkcs-8-PrivateKeyInfo", &pkcs8_asn)) != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } result = 0; error: asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE); return result; }
/** * gnutls_x509_rdn_get_oid: * @idn: should contain a DER encoded RDN sequence * @indx: Indicates which OID to return. Use 0 for the first one. * @buf: a pointer to a structure to hold the peer's name OID * @buf_size: holds the size of @buf * * This function will return the specified Object identifier, of the * RDN sequence. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@buf_size is * updated if the provided buffer is not long enough, otherwise a * negative error value. * * Since: 2.4.0 **/ int gnutls_x509_rdn_get_oid(const gnutls_datum_t * idn, int indx, void *buf, size_t * buf_size) { int result; ASN1_TYPE dn = ASN1_TYPE_EMPTY; if (buf_size == 0) { return GNUTLS_E_INVALID_REQUEST; } if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Name", &dn)) != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = _asn1_strict_der_decode(&dn, idn->data, idn->size, NULL); if (result != ASN1_SUCCESS) { /* couldn't decode DER */ gnutls_assert(); asn1_delete_structure(&dn); return _gnutls_asn2err(result); } result = _gnutls_x509_get_dn_oid(dn, "rdnSequence", indx, buf, buf_size); asn1_delete_structure(&dn); return result; }
/* generate the SubjectKeyID in a DER encoded extension */ int _gnutls_x509_ext_gen_key_id(const void *id, size_t id_size, gnutls_datum_t * der_ext) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; int result; result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.SubjectKeyIdentifier", &ext); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = asn1_write_value(ext, "", id, id_size); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&ext); return _gnutls_asn2err(result); } result = _gnutls_x509_der_encode(ext, "", der_ext, 0); asn1_delete_structure(&ext); if (result < 0) { gnutls_assert(); return result; } return 0; }
/* generate an INTEGER in a DER encoded extension */ int _gnutls_x509_ext_gen_number(const uint8_t * number, size_t nr_size, gnutls_datum_t * der_ext) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; int result; result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.CertificateSerialNumber", &ext); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = asn1_write_value(ext, "", number, nr_size); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&ext); return _gnutls_asn2err(result); } result = _gnutls_x509_der_encode(ext, "", der_ext, 0); asn1_delete_structure(&ext); if (result < 0) { gnutls_assert(); return result; } return 0; }
/* generate the keyUsage in a DER encoded extension * Use an ORed SEQUENCE of GNUTLS_KEY_* for usage. */ int _gnutls_x509_ext_gen_keyUsage(uint16_t usage, gnutls_datum_t * der_ext) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; int result; uint8_t str[2]; result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.KeyUsage", &ext); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } str[0] = usage & 0xff; str[1] = usage >> 8; result = asn1_write_value(ext, "", str, 9); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&ext); return _gnutls_asn2err(result); } result = _gnutls_x509_der_encode(ext, "", der_ext, 0); asn1_delete_structure(&ext); if (result < 0) { gnutls_assert(); return result; } return 0; }
/** * gnutls_x509_rdn_get2: * @idn: should contain a DER encoded RDN sequence * @buf: a pointer to a structure to hold the peer's name * @buf_size: holds the size of @buf * @flags: * * This function will return the name of the given RDN sequence. The * name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in * RFC4514. * * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output * format will match the format output by previous to 3.5.6 versions of GnuTLS * which was not not fully RFC4514-compliant. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@buf_size is * updated if the provided buffer is not long enough, otherwise a * negative error value. **/ int gnutls_x509_rdn_get2(const gnutls_datum_t * idn, gnutls_datum_t *str, unsigned flags) { int result; ASN1_TYPE dn = ASN1_TYPE_EMPTY; if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Name", &dn)) != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = _asn1_strict_der_decode(&dn, idn->data, idn->size, NULL); if (result != ASN1_SUCCESS) { /* couldn't decode DER */ gnutls_assert(); asn1_delete_structure(&dn); return _gnutls_asn2err(result); } result = _gnutls_x509_get_dn(dn, "rdnSequence", str, flags); asn1_delete_structure(&dn); return result; }
/* Encodes and public key parameters into a * subjectPublicKeyInfo structure and stores it in der. */ int _gnutls_x509_encode_PKI_params (gnutls_datum_t *der, gnutls_pk_algorithm_t pk_algorithm, gnutls_pk_params_st * params) { int ret; ASN1_TYPE tmp; ret = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Certificate", &tmp); if (ret != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (ret); } ret = _gnutls_x509_encode_and_copy_PKI_params (tmp, "tbsCertificate.subjectPublicKeyInfo", pk_algorithm, params); if (ret != ASN1_SUCCESS) { gnutls_assert (); ret = _gnutls_asn2err (ret); goto cleanup; } ret = _gnutls_x509_der_encode(tmp, "tbsCertificate.subjectPublicKeyInfo", der, 0); cleanup: asn1_delete_structure (&tmp); return ret; }
/* Writes the value of the datum in the given ASN1_TYPE. If str is non * (0) it encodes it as OCTET STRING. */ int _gnutls_x509_write_value (ASN1_TYPE c, const char *root, const gnutls_datum_t * data, int str) { int result; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; gnutls_datum_t val = { NULL, 0 }; if (str) { /* Convert it to OCTET STRING */ if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = asn1_write_value (c2, "", data->data, data->size); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = _gnutls_x509_der_encode (c2, "", &val, 0); if (result < 0) { gnutls_assert (); goto cleanup; } } else { val.data = data->data; val.size = data->size; } /* Write the data. */ result = asn1_write_value (c, root, val.data, val.size); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = 0; cleanup: asn1_delete_structure (&c2); if (val.data != data->data) _gnutls_free_datum (&val); return result; }
/* generate the proxyCertInfo in a DER encoded extension */ int _gnutls_x509_ext_gen_proxyCertInfo(int pathLenConstraint, const char *policyLanguage, const char *policy, size_t sizeof_policy, gnutls_datum_t * der_ext) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; int result; result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.ProxyCertInfo", &ext); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } if (pathLenConstraint < 0) { result = asn1_write_value(ext, "pCPathLenConstraint", NULL, 0); if (result != ASN1_SUCCESS) result = _gnutls_asn2err(result); } else result = _gnutls_x509_write_uint32(ext, "pCPathLenConstraint", pathLenConstraint); if (result < 0) { gnutls_assert(); asn1_delete_structure(&ext); return result; } result = asn1_write_value(ext, "proxyPolicy.policyLanguage", policyLanguage, 1); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&ext); return _gnutls_asn2err(result); } result = asn1_write_value(ext, "proxyPolicy.policy", policy, sizeof_policy); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&ext); return _gnutls_asn2err(result); } result = _gnutls_x509_der_encode(ext, "", der_ext, 0); asn1_delete_structure(&ext); if (result < 0) { gnutls_assert(); return result; } return 0; }
/* generate the basicConstraints in a DER encoded extension * Use 0 or 1 (TRUE) for CA. * Use negative error codes for pathLenConstraint to indicate that the field * should not be present, >= 0 to indicate set values. */ int _gnutls_x509_ext_gen_basicConstraints (int CA, int pathLenConstraint, gnutls_datum_t * der_ext) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; const char *str; int result; if (CA == 0) str = "FALSE"; else str = "TRUE"; result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_write_value (ext, "cA", str, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&ext); return _gnutls_asn2err (result); } if (pathLenConstraint < 0) { result = asn1_write_value (ext, "pathLenConstraint", NULL, 0); if (result < 0) result = _gnutls_asn2err (result); } else result = _gnutls_x509_write_uint32 (ext, "pathLenConstraint", pathLenConstraint); if (result < 0) { gnutls_assert (); asn1_delete_structure (&ext); return result; } result = _gnutls_x509_der_encode (ext, "", der_ext, 0); asn1_delete_structure (&ext); if (result < 0) { gnutls_assert (); return result; } return 0; }
/*- * gnutls_x509_extract_dn - This function parses an RDN sequence * @idn: should contain a DER encoded RDN sequence * @rdn: a pointer to a structure to hold the name * * This function will return the name of the given RDN sequence. * The name will be returned as a gnutls_x509_dn structure. * Returns a negative error code in case of an error. * -*/ int gnutls_x509_extract_dn (const gnutls_datum_t * idn, gnutls_x509_dn * rdn) { ASN1_TYPE dn = ASN1_TYPE_EMPTY; int result; size_t len; if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Name", &dn)) != ASN1_SUCCESS) { return _gnutls_asn2err (result); } result = asn1_der_decoding (&dn, idn->data, idn->size, NULL); if (result != ASN1_SUCCESS) { /* couldn't decode DER */ asn1_delete_structure (&dn); return _gnutls_asn2err (result); } memset (rdn, 0, sizeof (gnutls_x509_dn)); len = sizeof (rdn->country); _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_COUNTRY_NAME, 0, 0, rdn->country, &len); len = sizeof (rdn->organization); _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_ORGANIZATION_NAME, 0, 0, rdn->organization, &len); len = sizeof (rdn->organizational_unit_name); _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, 0, rdn->organizational_unit_name, &len); len = sizeof (rdn->common_name); _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_COMMON_NAME, 0, 0, rdn->common_name, &len); len = sizeof (rdn->locality_name); _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_LOCALITY_NAME, 0, 0, rdn->locality_name, &len); len = sizeof (rdn->state_or_province_name); _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, 0, rdn->state_or_province_name, &len); len = sizeof (rdn->email); _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_PKCS9_EMAIL, 0, 0, rdn->email, &len); asn1_delete_structure (&dn); return 0; }
/* Creates an empty PFX structure for the PKCS12 structure. */ static int create_empty_pfx (ASN1_TYPE pkcs12) { uint8_t three = 3; int result; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; /* Use version 3 */ result = asn1_write_value (pkcs12, "version", &three, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Write the content type of the data */ result = asn1_write_value (pkcs12, "authSafe.contentType", DATA_OID, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Check if the authenticatedSafe content is empty, and encode a * null one in that case. */ if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe", &c2)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = _gnutls_x509_der_encode_and_copy (c2, "", pkcs12, "authSafe.content", 1); if (result < 0) { gnutls_assert (); goto cleanup; } asn1_delete_structure (&c2); return 0; cleanup: asn1_delete_structure (&c2); return result; }
/* Convert the given name to GeneralNames in a DER encoded extension. * This is the same as subject alternative name. */ int _gnutls_x509_ext_gen_subject_alt_name (gnutls_x509_subject_alt_name_t type, const void *data, unsigned int data_size, gnutls_datum_t * prev_der_ext, gnutls_datum_t * der_ext) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; int result; result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.GeneralNames", &ext); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } if (prev_der_ext != NULL && prev_der_ext->data != NULL && prev_der_ext->size != 0) { result = asn1_der_decoding (&ext, prev_der_ext->data, prev_der_ext->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&ext); return _gnutls_asn2err (result); } } result = write_new_general_name (ext, "", type, data, data_size); if (result < 0) { gnutls_assert (); asn1_delete_structure (&ext); return result; } result = _gnutls_x509_der_encode (ext, "", der_ext, 0); asn1_delete_structure (&ext); if (result < 0) { gnutls_assert (); return result; } return 0; }
/* Decodes an octet string. Leave string_type null for a normal * octet string. Otherwise put something like BMPString, PrintableString * etc. */ int _gnutls_x509_decode_octet_string (const char *string_type, const opaque * der, size_t der_size, opaque * output, size_t * output_size) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result, tmp_output_size; char strname[64]; if (string_type == NULL) _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.pkcs-7-Data"); else { _gnutls_str_cpy (strname, sizeof (strname), "PKIX1."); _gnutls_str_cat (strname, sizeof (strname), string_type); } if ((result = asn1_create_element (_gnutls_get_pkix (), strname, &c2)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = asn1_der_decoding (&c2, der, der_size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } tmp_output_size = *output_size; result = asn1_read_value (c2, "", output, &tmp_output_size); *output_size = tmp_output_size; if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = 0; cleanup: if (c2) asn1_delete_structure (&c2); return result; }
/* extract the basicConstraints from the DER encoded extension */ int _gnutls_x509_ext_extract_basicConstraints (unsigned int *CA, int *pathLenConstraint, uint8_t * extnValue, int extnValueLen) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; char str[128]; int len, result; if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&ext); return _gnutls_asn2err (result); } if (pathLenConstraint) { result = _gnutls_x509_read_uint (ext, "pathLenConstraint", (unsigned int*)pathLenConstraint); if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) *pathLenConstraint = -1; else if (result != GNUTLS_E_SUCCESS) { gnutls_assert (); asn1_delete_structure (&ext); return _gnutls_asn2err (result); } } /* the default value of cA is false. */ len = sizeof (str) - 1; result = asn1_read_value (ext, "cA", str, &len); if (result == ASN1_SUCCESS && strcmp (str, "TRUE") == 0) *CA = 1; else *CA = 0; asn1_delete_structure (&ext); 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 encode_user_notice(const gnutls_datum_t * txt, gnutls_datum_t * der_data) { int result; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.UserNotice", &c2)) != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } /* delete noticeRef */ result = asn1_write_value(c2, "noticeRef", NULL, 0); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } result = asn1_write_value(c2, "explicitText", "utf8String", 1); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } result = asn1_write_value(c2, "explicitText.utf8String", txt->data, txt->size); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } result = _gnutls_x509_der_encode(c2, "", der_data, 0); if (result < 0) { gnutls_assert(); goto error; } result = 0; error: asn1_delete_structure(&c2); return result; }
/** * gnutls_x509_dn_init: * @dn: the object to be initialized * * This function initializes a #gnutls_x509_dn_t structure. * * The object returned must be deallocated using * gnutls_x509_dn_deinit(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.4.0 **/ int gnutls_x509_dn_init(gnutls_x509_dn_t * dn) { int result; ASN1_TYPE tmpdn = ASN1_TYPE_EMPTY; if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Name", &tmpdn)) != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } *dn = tmpdn; return 0; }
/** * gnutls_x509_dn_init: * @dn: the object to be initialized * * This function initializes a #gnutls_x509_dn_t type. * * The object returned must be deallocated using * gnutls_x509_dn_deinit(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.4.0 **/ int gnutls_x509_dn_init(gnutls_x509_dn_t * dn) { int result; *dn = gnutls_calloc(1, sizeof(gnutls_x509_dn_st)); if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Name", &(*dn)->asn)) != ASN1_SUCCESS) { gnutls_assert(); gnutls_free(*dn); return _gnutls_asn2err(result); } return 0; }
/** * gnutls_x509_crl_init: * @crl: The structure to be initialized * * This function will initialize a CRL structure. CRL stands for * Certificate Revocation List. A revocation list usually contains * lists of certificate serial numbers that have been revoked by an * Authority. The revocation lists are always signed with the * authority's private key. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crl_init(gnutls_x509_crl_t * crl) { *crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int)); if (*crl) { int result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.CertificateList", &(*crl)->crl); if (result != ASN1_SUCCESS) { gnutls_assert(); gnutls_free(*crl); return _gnutls_asn2err(result); } return 0; /* success */ } return GNUTLS_E_MEMORY_ERROR; }
/** * gnutls_pkcs12_init: * @pkcs12: The structure to be initialized * * This function will initialize a PKCS12 structure. PKCS12 structures * usually contain lists of X.509 Certificates and X.509 Certificate * revocation lists. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12) { *pkcs12 = gnutls_calloc(1, sizeof(gnutls_pkcs12_int)); if (*pkcs12) { int result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.pkcs-12-PFX", &(*pkcs12)->pkcs12); if (result != ASN1_SUCCESS) { gnutls_assert(); gnutls_free(*pkcs12); return _gnutls_asn2err(result); } return 0; /* success */ } return GNUTLS_E_MEMORY_ERROR; }
static int pkcs12_reinit(gnutls_pkcs12_t pkcs12) { int result; if (pkcs12->pkcs12) asn1_delete_structure(&pkcs12->pkcs12); result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.pkcs-12-PFX", &pkcs12->pkcs12); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } return 0; }
static int _get_authority_key_id(gnutls_x509_crl_t cert, ASN1_TYPE * c2, unsigned int *critical) { int ret; gnutls_datum_t id; *c2 = ASN1_TYPE_EMPTY; if (cert == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } if ((ret = _gnutls_x509_crl_get_extension(cert, "2.5.29.35", 0, &id, critical)) < 0) { return gnutls_assert_val(ret); } if (id.size == 0 || id.data == NULL) { gnutls_assert(); return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; } ret = asn1_create_element (_gnutls_get_pkix(), "PKIX1.AuthorityKeyIdentifier", c2); if (ret != ASN1_SUCCESS) { gnutls_assert(); _gnutls_free_datum(&id); return _gnutls_asn2err(ret); } ret = asn1_der_decoding(c2, id.data, id.size, NULL); _gnutls_free_datum(&id); if (ret != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(c2); return _gnutls_asn2err(ret); } return 0; }
/* extract an INTEGER from the DER encoded extension */ int _gnutls_x509_ext_extract_number (uint8_t * number, size_t * _nr_size, uint8_t * extnValue, int extnValueLen) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; int result; int nr_size = *_nr_size; /* here it doesn't matter so much that we use CertificateSerialNumber. It is equal * to using INTEGER. */ if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.CertificateSerialNumber", &ext)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&ext); return _gnutls_asn2err (result); } /* the default value of cA is false. */ result = asn1_read_value (ext, "", number, &nr_size); if (result != ASN1_SUCCESS) result = _gnutls_asn2err (result); else result = 0; *_nr_size = nr_size; asn1_delete_structure (&ext); return result; }
/* Here we only extract the KeyUsage field, from the DER encoded * extension. */ int _gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage, uint8_t * extnValue, int extnValueLen) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; int len, result; uint8_t str[2]; str[0] = str[1] = 0; *keyUsage = 0; if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&ext); return _gnutls_asn2err (result); } len = sizeof (str); result = asn1_read_value (ext, "", str, &len); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&ext); return 0; } *keyUsage = str[0] | (str[1] << 8); asn1_delete_structure (&ext); return 0; }
static int crl_reinit(gnutls_x509_crl_t crl) { int result; if (crl->crl) asn1_delete_structure(&crl->crl); result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.CertificateList", &crl->crl); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } crl->rcache = NULL; crl->rcache_idx = 0; crl->raw_issuer_dn.size = 0; return 0; }
/** * gnutls_x509_rdn_get - This function parses an RDN sequence and returns a string * @idn: should contain a DER encoded RDN sequence * @buf: a pointer to a structure to hold the peer's name * @sizeof_buf: holds the size of @buf * * This function will return the name of the given RDN sequence. The * name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in * RFC2253. * * If the provided buffer is not long enough, returns * GNUTLS_E_SHORT_MEMORY_BUFFER and *sizeof_buf will be updated. On * success 0 is returned. * **/ int gnutls_x509_rdn_get (const gnutls_datum_t * idn, char *buf, size_t * sizeof_buf) { int result; ASN1_TYPE dn = ASN1_TYPE_EMPTY; if (sizeof_buf == 0) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } if (buf) buf[0] = 0; if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Name", &dn)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&dn, idn->data, idn->size, NULL); if (result != ASN1_SUCCESS) { /* couldn't decode DER */ gnutls_assert (); asn1_delete_structure (&dn); return _gnutls_asn2err (result); } result = _gnutls_x509_parse_dn (dn, "rdnSequence", buf, sizeof_buf); asn1_delete_structure (&dn); return result; }
/** * gnutls_x509_rdn_get_by_oid: * @idn: should contain a DER encoded RDN sequence * @oid: an Object Identifier * @indx: In case multiple same OIDs exist in the RDN indicates which * to send. Use 0 for the first one. * @raw_flag: If non-zero then the raw DER data are returned. * @buf: a pointer to a structure to hold the peer's name * @buf_size: holds the size of @buf * * This function will return the name of the given Object identifier, * of the RDN sequence. The name will be encoded using the rules * from RFC4514. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@buf_size is * updated if the provided buffer is not long enough, otherwise a * negative error value. **/ int gnutls_x509_rdn_get_by_oid(const gnutls_datum_t * idn, const char *oid, int indx, unsigned int raw_flag, void *buf, size_t * buf_size) { int result; ASN1_TYPE dn = ASN1_TYPE_EMPTY; gnutls_datum_t td; if (buf_size == 0) { return GNUTLS_E_INVALID_REQUEST; } if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Name", &dn)) != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = _asn1_strict_der_decode(&dn, idn->data, idn->size, NULL); if (result != ASN1_SUCCESS) { /* couldn't decode DER */ gnutls_assert(); asn1_delete_structure(&dn); return _gnutls_asn2err(result); } result = _gnutls_x509_parse_dn_oid(dn, "rdnSequence", oid, indx, raw_flag, &td); asn1_delete_structure(&dn); if (result < 0) return gnutls_assert_val(result); return _gnutls_strdatum_to_buf(&td, buf, buf_size); }
/* Converts a PKCS #8 key to * an internal structure (gnutls_private_key) * (normally a PKCS #1 encoded RSA key) */ static int pkcs8_key_decode(const gnutls_datum_t * raw_key, const char *password, gnutls_x509_privkey_t pkey, unsigned int decrypt) { int result; ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY; if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.pkcs-8-EncryptedPrivateKeyInfo", &pkcs8_asn)) != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } result = _asn1_strict_der_decode(&pkcs8_asn, raw_key->data, raw_key->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } if (decrypt) result = pkcs8_key_decrypt(raw_key, pkcs8_asn, password, pkey); else result = 0; error: asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE); return result; }
/* Decodes the PKCS #12 auth_safe, and returns the allocated raw data, * which holds them. Returns an ASN1_TYPE of authenticatedSafe. */ static int _decode_pkcs12_auth_safe (ASN1_TYPE pkcs12, ASN1_TYPE * authen_safe, gnutls_datum_t * raw) { char oid[MAX_OID_SIZE]; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; gnutls_datum_t auth_safe = { NULL, 0 }; int len, result; char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; len = sizeof (oid) - 1; result = asn1_read_value (pkcs12, "authSafe.contentType", oid, &len); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } if (strcmp (oid, DATA_OID) != 0) { gnutls_assert (); _gnutls_x509_log ("Unknown PKCS12 Content OID '%s'\n", oid); return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE; } /* Step 1. Read the content data */ result = _gnutls_x509_read_value (pkcs12, "authSafe.content", &auth_safe, 1); if (result < 0) { gnutls_assert (); goto cleanup; } /* Step 2. Extract the authenticatedSafe. */ if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe", &c2)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = asn1_der_decoding (&c2, auth_safe.data, auth_safe.size, error_str); if (result != ASN1_SUCCESS) { gnutls_assert (); _gnutls_x509_log ("DER error: %s\n", error_str); result = _gnutls_asn2err (result); goto cleanup; } if (raw == NULL) { _gnutls_free_datum (&auth_safe); } else { raw->data = auth_safe.data; raw->size = auth_safe.size; } if (authen_safe) *authen_safe = c2; else asn1_delete_structure (&c2); return 0; cleanup: if (c2) asn1_delete_structure (&c2); _gnutls_free_datum (&auth_safe); return result; }