/* * This function writes and encodes the parameters for DSS or RSA keys. * This is the "signatureAlgorithm" fields. */ int _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name, gnutls_pk_algorithm_t pk_algorithm, gnutls_digest_algorithm_t dig, bigint_t * params, int params_size) { int result; char name[128]; const char *pk; _gnutls_str_cpy (name, sizeof (name), dst_name); _gnutls_str_cat (name, sizeof (name), ".algorithm"); pk = _gnutls_x509_sign_to_oid (pk_algorithm, HASH2MAC (dig)); if (pk == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* write the OID. */ result = asn1_write_value (dst, name, pk, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } _gnutls_str_cpy (name, sizeof (name), dst_name); _gnutls_str_cat (name, sizeof (name), ".parameters"); result = asn1_write_value (dst, name, NULL, 0); if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) { /* Here we ignore the element not found error, since this * may have been disabled before. */ gnutls_assert (); return _gnutls_asn2err (result); } return 0; }
/** * gnutls_x509_crl_import - import a DER or PEM encoded CRL * @crl: The structure to store the parsed CRL. * @data: The DER or PEM encoded CRL. * @format: One of DER or PEM * * This function will convert the given DER or PEM encoded CRL * to the native #gnutls_x509_crl_t format. The output will be stored in 'crl'. * * If the CRL is PEM encoded it should have a header of "X509 CRL". * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_x509_crl_import (gnutls_x509_crl_t crl, const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format) { int result = 0, need_free = 0; gnutls_datum_t _data; _data.data = data->data; _data.size = data->size; if (crl == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* If the CRL is in PEM format then decode it */ if (format == GNUTLS_X509_FMT_PEM) { opaque *out; result = _gnutls_fbase64_decode (PEM_CRL, data->data, data->size, &out); if (result <= 0) { if (result == 0) result = GNUTLS_E_INTERNAL_ERROR; gnutls_assert (); return result; } _data.data = out; _data.size = result; need_free = 1; } result = asn1_der_decoding (&crl->crl, _data.data, _data.size, NULL); if (result != ASN1_SUCCESS) { result = _gnutls_asn2err (result); gnutls_assert (); goto cleanup; } if (need_free) _gnutls_free_datum (&_data); return 0; cleanup: if (need_free) _gnutls_free_datum (&_data); return result; }
/** * gnutls_x509_crl_import: * @crl: The structure to store the parsed CRL. * @data: The DER or PEM encoded CRL. * @format: One of DER or PEM * * This function will convert the given DER or PEM encoded CRL * to the native #gnutls_x509_crl_t format. The output will be stored in 'crl'. * * If the CRL is PEM encoded it should have a header of "X509 CRL". * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crl_import(gnutls_x509_crl_t crl, const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format) { int result = 0, need_free = 0; gnutls_datum_t _data; _data.data = data->data; _data.size = data->size; if (crl == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } /* If the CRL is in PEM format then decode it */ if (format == GNUTLS_X509_FMT_PEM) { result = _gnutls_fbase64_decode(PEM_CRL, data->data, data->size, &_data); if (result < 0) { gnutls_assert(); return result; } need_free = 1; } result = asn1_der_decoding(&crl->crl, _data.data, _data.size, NULL); if (result != ASN1_SUCCESS) { result = _gnutls_asn2err(result); gnutls_assert(); goto cleanup; } result = _gnutls_x509_get_raw_dn2(crl->crl, &_data, "tbsCertList.issuer.rdnSequence", &crl->raw_issuer_dn); if (result < 0) { gnutls_assert(); goto cleanup; } if (need_free) _gnutls_free_datum(&_data); return 0; cleanup: if (need_free) _gnutls_free_datum(&_data); _gnutls_free_datum(&crl->raw_issuer_dn); return result; }
/** * gnutls_pkcs7_get_crl_raw: * @pkcs7: should contain a #gnutls_pkcs7_t structure * @indx: contains the index of the crl to extract * @crl: the contents of the crl will be copied there (may be null) * @crl_size: should hold the size of the crl * * This function will return a crl of the PKCS7 or RFC2630 crl set. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. If the provided buffer is not long enough, * then @crl_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER is * returned. After the last crl has been read * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. **/ int gnutls_pkcs7_get_crl_raw(gnutls_pkcs7_t pkcs7, int indx, void *crl, size_t * crl_size) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result; char root2[ASN1_MAX_NAME_SIZE]; gnutls_datum_t tmp = { NULL, 0 }; int start, end; if (pkcs7 == NULL || crl_size == NULL) return GNUTLS_E_INVALID_REQUEST; /* Step 1. decode the signed data. */ result = _decode_pkcs7_signed_data(pkcs7->pkcs7, &c2, &tmp); if (result < 0) { gnutls_assert(); return result; } /* Step 2. Parse the CertificateSet */ snprintf(root2, sizeof(root2), "crls.?%u", indx + 1); /* Get the raw CRL */ result = asn1_der_decoding_startEnd(c2, tmp.data, tmp.size, root2, &start, &end); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } end = end - start + 1; if ((unsigned) end > *crl_size) { *crl_size = end; result = GNUTLS_E_SHORT_MEMORY_BUFFER; goto cleanup; } if (crl) memcpy(crl, &tmp.data[start], end); *crl_size = end; result = 0; cleanup: _gnutls_free_datum(&tmp); if (c2) asn1_delete_structure(&c2); return result; }
/* decodes the Dss-Sig-Value structure */ int _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r, bigint_t * s) { ASN1_TYPE sig; int result; if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSASignatureValue", &sig)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&sig, sig_value->data, sig_value->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&sig); return _gnutls_asn2err (result); } result = _gnutls_x509_read_int (sig, "r", r); if (result < 0) { gnutls_assert (); asn1_delete_structure (&sig); return result; } result = _gnutls_x509_read_int (sig, "s", s); if (result < 0) { gnutls_assert (); _gnutls_mpi_release (s); asn1_delete_structure (&sig); return result; } asn1_delete_structure (&sig); return 0; }
/* Sets the time in time_t in the ASN1_TYPE given. Where should * be something like "tbsCertList.thisUpdate". */ int _gnutls_x509_set_time(ASN1_TYPE c2, const char *where, time_t tim, int nochoice) { char str_time[MAX_TIME]; char name[128]; int result, len; if (nochoice != 0) { result = gtime2generalTime(tim, str_time, sizeof(str_time)); if (result < 0) return gnutls_assert_val(result); len = strlen(str_time); result = asn1_write_value(c2, where, str_time, len); if (result != ASN1_SUCCESS) return gnutls_assert_val(_gnutls_asn2err(result)); return 0; } _gnutls_str_cpy(name, sizeof(name), where); if ((result = asn1_write_value(c2, name, "generalTime", 1)) < 0) { gnutls_assert(); return _gnutls_asn2err(result); } result = gtime2generalTime(tim, str_time, sizeof(str_time)); if (result < 0) { gnutls_assert(); return result; } _gnutls_str_cat(name, sizeof(name), ".generalTime"); len = strlen(str_time); result = asn1_write_value(c2, name, str_time, len); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } return 0; }
/** * gnutls_x509_crl_get_signature - Returns the CRL's signature * @crl: should contain a gnutls_x509_crl_t structure * @sig: a pointer where the signature part will be copied (may be null). * @sizeof_sig: initially holds the size of @sig * * This function will extract the signature field of a CRL. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. and a negative value on error. **/ int gnutls_x509_crl_get_signature (gnutls_x509_crl_t crl, char *sig, size_t * sizeof_sig) { int result; int bits; unsigned int len; if (crl == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } bits = 0; result = asn1_read_value (crl->crl, "signature", NULL, &bits); if (result != ASN1_MEM_ERROR) { gnutls_assert (); return _gnutls_asn2err (result); } if (bits % 8 != 0) { gnutls_assert (); return GNUTLS_E_CERTIFICATE_ERROR; } len = bits / 8; if (*sizeof_sig < len) { *sizeof_sig = bits / 8; return GNUTLS_E_SHORT_MEMORY_BUFFER; } result = asn1_read_value (crl->crl, "signature", sig, &len); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } return 0; }
/* * some x509 certificate parsing functions that relate to MPI parameter * extraction. This reads the BIT STRING subjectPublicKey. * Returns 2 parameters (m,e). */ int _gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&spk, der, dersize, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&spk); return _gnutls_asn2err (result); } if ((result = _gnutls_x509_read_int (spk, "modulus", ¶ms[0])) < 0) { gnutls_assert (); asn1_delete_structure (&spk); return GNUTLS_E_ASN1_GENERIC_ERROR; } if ((result = _gnutls_x509_read_int (spk, "publicExponent", ¶ms[1])) < 0) { gnutls_assert (); _gnutls_mpi_release (¶ms[0]); asn1_delete_structure (&spk); return GNUTLS_E_ASN1_GENERIC_ERROR; } asn1_delete_structure (&spk); return 0; }
/* Decodes an octet string. The etype specifies the string type. * The returned string is always null terminated (but null is not * included in size). */ int _gnutls_x509_decode_string(unsigned int etype, const uint8_t * der, size_t der_size, gnutls_datum_t * output, unsigned allow_ber) { int ret; uint8_t *str; unsigned int str_size, len; gnutls_datum_t td; if (allow_ber) ret = asn1_decode_simple_ber(etype, der, der_size, &str, &str_size, NULL); else ret = asn1_decode_simple_der(etype, der, der_size, (const uint8_t**)&str, &str_size); if (ret != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(ret); return ret; } td.size = str_size; td.data = gnutls_malloc(str_size + 1); if (td.data == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); memcpy(td.data, str, str_size); td.data[str_size] = 0; if (allow_ber) free(str); ret = make_printable_string(etype, &td, output); if (ret == GNUTLS_E_INVALID_REQUEST) { /* unsupported etype */ output->data = td.data; output->size = td.size; ret = 0; } else if (ret <= 0) { _gnutls_free_datum(&td); } /* Refuse to deal with strings containing NULs. */ if (etype != ASN1_ETYPE_OCTET_STRING) { if (output->data) len = strlen((void *) output->data); else len = 0; if (len != (size_t) output->size) { _gnutls_free_datum(output); ret = gnutls_assert_val(GNUTLS_E_ASN1_EMBEDDED_NULL_IN_STRING); } } return ret; }
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; }
/** * gnutls_pkcs7_import: * @pkcs7: The structure to store the parsed PKCS7. * @data: The DER or PEM encoded PKCS7. * @format: One of DER or PEM * * This function will convert the given DER or PEM encoded PKCS7 to * the native #gnutls_pkcs7_t format. The output will be stored in * @pkcs7. * * If the PKCS7 is PEM encoded it should have a header of "PKCS7". * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_pkcs7_import (gnutls_pkcs7_t pkcs7, const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format) { int result = 0, need_free = 0; gnutls_datum_t _data; if (pkcs7 == NULL) return GNUTLS_E_INVALID_REQUEST; _data.data = data->data; _data.size = data->size; /* If the PKCS7 is in PEM format then decode it */ if (format == GNUTLS_X509_FMT_PEM) { uint8_t *out; result = _gnutls_fbase64_decode (PEM_PKCS7, data->data, data->size, &out); if (result <= 0) { if (result == 0) result = GNUTLS_E_INTERNAL_ERROR; gnutls_assert (); return result; } _data.data = out; _data.size = result; need_free = 1; } result = asn1_der_decoding (&pkcs7->pkcs7, _data.data, _data.size, NULL); if (result != ASN1_SUCCESS) { result = _gnutls_asn2err (result); gnutls_assert (); goto cleanup; } if (need_free) _gnutls_free_datum (&_data); return 0; cleanup: if (need_free) _gnutls_free_datum (&_data); return result; }
/* 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; }
/* * some x509 certificate functions that relate to MPI parameter * setting. This writes the BIT STRING subjectPublicKey. * Needs 2 parameters (m,e). * * Allocates the space used to store the DER data. */ int _gnutls_x509_write_rsa_params (bigint_t * params, int params_size, gnutls_datum_t * der) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; der->data = NULL; der->size = 0; if (params_size < 2) { gnutls_assert (); result = GNUTLS_E_INVALID_REQUEST; goto cleanup; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = _gnutls_x509_write_int (spk, "modulus", params[0], 1); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_x509_write_int (spk, "publicExponent", params[1], 1); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_x509_der_encode (spk, "", der, 0); if (result < 0) { gnutls_assert (); goto cleanup; } asn1_delete_structure (&spk); return 0; cleanup: asn1_delete_structure (&spk); return result; }
/** * gnutls_pkcs12_import: * @pkcs12: The structure to store the parsed PKCS12. * @data: The DER or PEM encoded PKCS12. * @format: One of DER or PEM * @flags: an ORed sequence of gnutls_privkey_pkcs8_flags * * This function will convert the given DER or PEM encoded PKCS12 * to the native gnutls_pkcs12_t format. The output will be stored in 'pkcs12'. * * If the PKCS12 is PEM encoded it should have a header of "PKCS12". * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_pkcs12_import (gnutls_pkcs12_t pkcs12, const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format, unsigned int flags) { int result = 0, need_free = 0; gnutls_datum_t _data; char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; _data.data = data->data; _data.size = data->size; if (pkcs12 == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* If the PKCS12 is in PEM format then decode it */ if (format == GNUTLS_X509_FMT_PEM) { result = _gnutls_fbase64_decode (PEM_PKCS12, data->data, data->size, &_data); if (result < 0) { gnutls_assert (); return result; } need_free = 1; } result = asn1_der_decoding (&pkcs12->pkcs12, _data.data, _data.size, error_str); if (result != ASN1_SUCCESS) { result = _gnutls_asn2err (result); _gnutls_debug_log ("DER error: %s\n", error_str); gnutls_assert (); goto cleanup; } if (need_free) _gnutls_free_datum (&_data); return 0; cleanup: if (need_free) _gnutls_free_datum (&_data); return result; }
/* this function reads an integer * from asn1 structs. Combines the read and mpi_scan * steps. */ int _gnutls_x509_read_int (ASN1_TYPE node, const char *value, bigint_t * ret_mpi) { int result; opaque *tmpstr = NULL; int tmpstr_size; tmpstr_size = 0; result = asn1_read_value (node, value, NULL, &tmpstr_size); if (result != ASN1_MEM_ERROR) { gnutls_assert (); return _gnutls_asn2err (result); } tmpstr = gnutls_malloc (tmpstr_size); if (tmpstr == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } result = asn1_read_value (node, value, tmpstr, &tmpstr_size); if (result != ASN1_SUCCESS) { gnutls_assert (); gnutls_free (tmpstr); return _gnutls_asn2err (result); } result = _gnutls_mpi_scan (ret_mpi, tmpstr, tmpstr_size); gnutls_free (tmpstr); if (result < 0) { gnutls_assert (); return result; } return 0; }
/* * This function writes the parameters for DSS keys. * Needs 3 parameters (p,q,g). * * Allocates the space used to store the DER data. */ static int _gnutls_x509_write_dsa_params(gnutls_pk_params_st * params, gnutls_datum_t * der) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; der->data = NULL; der->size = 0; if (params->params_nr < DSA_PUBLIC_PARAMS - 1) { gnutls_assert(); result = GNUTLS_E_INVALID_REQUEST; goto cleanup; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn(), "GNUTLS.DSAParameters", &spk)) != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = _gnutls_x509_write_int(spk, "p", params->params[0], 1); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_write_int(spk, "q", params->params[1], 1); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_write_int(spk, "g", params->params[2], 1); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_der_encode(spk, "", der, 0); if (result < 0) { gnutls_assert(); goto cleanup; } result = 0; cleanup: asn1_delete_structure(&spk); return result; }
int _gnutls_x509_get_dn(ASN1_TYPE asn1_struct, const char *asn1_rdn_name, gnutls_datum_t * dn, unsigned flags) { gnutls_buffer_st out_str; int i, k1, result; _gnutls_buffer_init(&out_str); result = asn1_number_of_elements(asn1_struct, asn1_rdn_name, &k1); if (result != ASN1_SUCCESS) { if (result == ASN1_ELEMENT_NOT_FOUND || result == ASN1_VALUE_NOT_FOUND) { result = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); } else { gnutls_assert(); result = _gnutls_asn2err(result); } goto cleanup; } if (k1 == 0) { gnutls_assert(); result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; goto cleanup; } if (flags & GNUTLS_X509_DN_FLAG_COMPAT) { for (i=0;i<k1;i++) { result = append_elements(asn1_struct, asn1_rdn_name, &out_str, i+1, (i==(k1-1))?1:0); if (result < 0) { gnutls_assert(); goto cleanup; } } } else { while (k1 > 0) { result = append_elements(asn1_struct, asn1_rdn_name, &out_str, k1, k1==1?1:0); if (result < 0) { gnutls_assert(); goto cleanup; } k1--; } } return _gnutls_buffer_to_datum(&out_str, dn, 1); cleanup: _gnutls_buffer_clear(&out_str); return result; }
/** * 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_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; }
/** * gnutls_x509_crq_sign2 - This function will sign a Certificate request with a key * @crq: should contain a gnutls_x509_crq_t structure * @key: holds a private key * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing. * @flags: must be 0 * * This function will sign the certificate request with a private key. * This must be the same key as the one used in gnutls_x509_crt_set_key() since a * certificate request is self signed. * * This must be the last step in a certificate request generation since all * the previously set parameters are now signed. * * Returns 0 on success. * **/ int gnutls_x509_crq_sign2 (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key, gnutls_digest_algorithm_t dig, unsigned int flags) { int result; gnutls_datum_t signature; if (crq == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* Step 1. Self sign the request. */ result = _gnutls_x509_sign_tbs (crq->crq, "certificationRequestInfo", dig, key, &signature); if (result < 0) { gnutls_assert (); return result; } /* Step 2. write the signature (bits) */ result = asn1_write_value (crq->crq, "signature", signature.data, signature.size * 8); _gnutls_free_datum (&signature); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } /* Step 3. Write the signatureAlgorithm field. */ result = _gnutls_x509_write_sig_params (crq->crq, "signatureAlgorithm", key->pk_algorithm, dig, key->params, key->params_size); if (result < 0) { gnutls_assert (); return result; } return 0; }
/* generate the AuthorityKeyID in a DER encoded extension */ int _gnutls_x509_ext_gen_auth_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.AuthorityKeyIdentifier", &ext); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_write_value (ext, "keyIdentifier", id, id_size); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&ext); return _gnutls_asn2err (result); } asn1_write_value (ext, "authorityCertIssuer", NULL, 0); asn1_write_value (ext, "authorityCertSerialNumber", NULL, 0); result = _gnutls_x509_der_encode (ext, "", der_ext, 0); asn1_delete_structure (&ext); if (result < 0) { gnutls_assert (); return result; } return 0; }
/* Writes the specified integer into the specified node. */ int _gnutls_x509_write_int (ASN1_TYPE node, const char *value, bigint_t mpi, int lz) { opaque *tmpstr; size_t s_len; int result; s_len = 0; if (lz) result = _gnutls_mpi_print_lz (mpi, NULL, &s_len); else result = _gnutls_mpi_print (mpi, NULL, &s_len); if (result != GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_assert (); return result; } tmpstr = gnutls_malloc (s_len); if (tmpstr == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } if (lz) result = _gnutls_mpi_print_lz (mpi, tmpstr, &s_len); else result = _gnutls_mpi_print (mpi, tmpstr, &s_len); if (result != 0) { gnutls_assert (); gnutls_free (tmpstr); return GNUTLS_E_MPI_PRINT_FAILED; } result = asn1_write_value (node, value, tmpstr, s_len); gnutls_free (tmpstr); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } return 0; }
/** * gnutls_pkcs7_delete_crl: * @pkcs7: should contain a #gnutls_pkcs7_t structure * @indx: the index of the crl to delete * * This function will delete a crl from a PKCS7 or RFC2630 crl set. * Index starts from 0. Returns 0 on success. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_pkcs7_delete_crl (gnutls_pkcs7_t pkcs7, int indx) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result; char root2[ASN1_MAX_NAME_SIZE]; if (pkcs7 == NULL) return GNUTLS_E_INVALID_REQUEST; /* Step 1. Decode the signed data. */ result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL); if (result < 0) { gnutls_assert (); return result; } /* Step 2. Delete the crl. */ snprintf (root2, sizeof (root2), "crls.?%u", indx + 1); result = asn1_write_value (c2, root2, NULL, 0); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Step 3. Replace the old content with the new */ result = _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0); if (result < 0) { gnutls_assert (); goto cleanup; } asn1_delete_structure (&c2); return 0; cleanup: if (c2) asn1_delete_structure (&c2); return result; }
/* encodes the Dss-Sig-Value structure */ int _gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value, const gnutls_datum_t * r, const gnutls_datum_t * s) { ASN1_TYPE sig; int result; if ((result = asn1_create_element(_gnutls_get_gnutls_asn(), "GNUTLS.DSASignatureValue", &sig)) != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = asn1_write_value(sig, "r", r->data, r->size); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&sig); return _gnutls_asn2err(result); } result = asn1_write_value(sig, "s", s->data, s->size); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&sig); return _gnutls_asn2err(result); } result = _gnutls_x509_der_encode(sig, "", sig_value, 0); asn1_delete_structure(&sig); if (result < 0) return gnutls_assert_val(result); return 0; }
int _gnutls_x509_read_der_int (opaque * der, int dersize, bigint_t * out) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; /* == INTEGER */ if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_der_decoding (&spk, der, dersize, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&spk); return _gnutls_asn2err (result); } /* Read Y */ if ((result = _gnutls_x509_read_int (spk, "", out)) < 0) { gnutls_assert (); asn1_delete_structure (&spk); return _gnutls_asn2err (result); } asn1_delete_structure (&spk); return 0; }
/** * 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; }
/* 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; }
/* 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; }