/** * gnutls_x509_rdn_get_oid - This function parses an RDN sequence and returns an OID. * @idn: should contain a DER encoded RDN sequence * @indx: Indicates which OID to return. Use 0 for the first one. * @oid: a pointer to a structure to hold the peer's name OID * @sizeof_oid: holds the size of @oid * * This function will return the specified Object identifier, of the * RDN sequence. * * Returns GNUTLS_E_SHORT_MEMORY_BUFFER and updates *sizeof_buf if * the provided buffer is not long enough, and 0 on success. * **/ int gnutls_x509_rdn_get_oid (const gnutls_datum_t * idn, int indx, void *buf, size_t * sizeof_buf) { int result; ASN1_TYPE dn = ASN1_TYPE_EMPTY; if (sizeof_buf == 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_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_get_dn_oid (dn, "rdnSequence", indx, buf, sizeof_buf); asn1_delete_structure (&dn); return result; }
/* reads the curve from the certificate. * params[0-4]. It does NOT set params_nr. */ int _gnutls_x509_read_ecc_params (opaque * der, int dersize, gnutls_pk_params_st * params) { int ret; ASN1_TYPE spk = ASN1_TYPE_EMPTY; char oid[MAX_OID_SIZE]; int oid_size; if ((ret = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.ECParameters", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (ret); } ret = asn1_der_decoding (&spk, der, dersize, NULL); if (ret != ASN1_SUCCESS) { gnutls_assert (); ret = _gnutls_asn2err (ret); goto cleanup; } /* Read curve */ /* read the curve */ oid_size = sizeof(oid); ret = asn1_read_value(spk, "namedCurve", oid, &oid_size); if (ret != ASN1_SUCCESS) { gnutls_assert (); ret = _gnutls_asn2err (ret); goto cleanup; } params->flags = _gnutls_oid_to_ecc_curve(oid); if (params->flags == GNUTLS_ECC_CURVE_INVALID) { _gnutls_debug_log("Curve %s is not supported\n", oid); gnutls_assert(); ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE; goto cleanup; } ret = _gnutls_ecc_curve_fill_params(params->flags, params); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = 0; cleanup: asn1_delete_structure (&spk); return ret; }
/** * gnutls_x509_crq_import - This function will import a DER or PEM encoded Certificate request * @crq: The structure to store the parsed certificate request. * @data: The DER or PEM encoded certificate. * @format: One of DER or PEM * * This function will convert the given DER or PEM encoded Certificate * to the native gnutls_x509_crq_t format. The output will be stored in @cert. * * If the Certificate is PEM encoded it should have a header of "NEW CERTIFICATE REQUEST". * * Returns 0 on success. * **/ int gnutls_x509_crq_import (gnutls_x509_crq_t crq, const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format) { int result = 0, need_free = 0; gnutls_datum_t _data; if (crq == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } _data.data = data->data; _data.size = data->size; /* If the Certificate is in PEM format then decode it */ if (format == GNUTLS_X509_FMT_PEM) { opaque *out; /* Try the first header */ result = _gnutls_fbase64_decode (PEM_CRQ, data->data, data->size, &out); if (result <= 0) /* Go for the second header */ result = _gnutls_fbase64_decode (PEM_CRQ2, 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 (&crq->crq, _data.data, _data.size, NULL); if (result != ASN1_SUCCESS) { result = _gnutls_asn2err (result); gnutls_assert (); goto cleanup; } result = 0; cleanup: if (need_free) _gnutls_free_datum (&_data); return result; }
static void get_certificate (ASN1_TYPE cert_def, unsigned char *der, int der_len) { int result, len, start, end; unsigned char str[1024], str2[1024]; ASN1_TYPE cert2 = ASN1_TYPE_EMPTY; char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; asn1_create_element (cert_def, "PKIX1Implicit88.Certificate", &cert2); result = asn1_der_decoding (&cert2, der, der_len, errorDescription); if (result != ASN1_SUCCESS) { printf ("Problems with DER encoding\n"); return; } /* issuer */ get_Name_type (cert_def, cert2, "tbsCertificate.issuer", str); printf ("certificate:\nissuer :%s\n", str); /* subject */ get_Name_type (cert_def, cert2, "tbsCertificate.subject", str); printf ("subject:%s\n", str); /* Verify sign */ len = sizeof (str) - 1; result = asn1_read_value (cert2, "signatureAlgorithm.algorithm", str, &len); len = sizeof (str2) - 1; result = asn1_read_value (cert_def, "PKIX1Implicit88.id-dsa-with-sha1", str2, &len); if (!strcmp ((char *) str, (char *) str2)) { /* dsa-with-sha */ result = asn1_der_decoding_startEnd (cert2, der, der_len, "tbsCertificate", &start, &end); /* add the lines to calculate the sha on der[start]..der[end] */ len = sizeof (str) - 1; result = asn1_read_value (cert2, "signature", str, &len); /* compare the previous value to signature ( with issuer public key) */ } /* Use the next 3 lines to visit the certificate */ /* printf("-----------------\n"); asn1_visit_tree(cert2,""); printf("-----------------\n"); */ /* Clear the "certificate2" structure */ asn1_delete_structure (&cert2); }
/** * 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_pkcs12_import - This function will import a DER or PEM encoded PKCS12 structure * @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 0 on success. * **/ 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; _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) { opaque *out; result = _gnutls_fbase64_decode (PEM_PKCS12, 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 (&pkcs12->pkcs12, _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_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; }
/** * 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; }
/* 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; }
int _gnutls_krb5_der_to_principal(const gnutls_datum_t * der, gnutls_datum_t * name) { int ret, result; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; gnutls_buffer_st str; _gnutls_buffer_init(&str); result = asn1_create_element(_gnutls_get_gnutls_asn(), "GNUTLS.KRB5PrincipalName", &c2); if (result != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(result); goto cleanup; } result = asn1_der_decoding(&c2, der->data, der->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(result); goto cleanup; } ret = principal_to_str(c2, &str); if (ret < 0) { /* for some reason we cannot convert to a human readable string * the principal. Then we use the #HEX format. */ _gnutls_buffer_reset(&str); ret = _gnutls_buffer_append_data(&str, "#", 1); if (ret < 0) { gnutls_assert(); goto cleanup; } _gnutls_buffer_hexprint(&str, der->data, der->size); } asn1_delete_structure(&c2); return _gnutls_buffer_to_datum(&str, name, 1); cleanup: _gnutls_buffer_clear(&str); asn1_delete_structure(&c2); return ret; }
/** * gnutls_x509_dn_import: * @dn: the structure that will hold the imported DN * @data: should contain a DER encoded RDN sequence * * This function parses an RDN sequence and stores the result to a * #gnutls_x509_dn_t structure. The structure must have been initialized * with gnutls_x509_dn_init(). You may use gnutls_x509_dn_get_rdn_ava() to * decode the DN. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.4.0 **/ int gnutls_x509_dn_import(gnutls_x509_dn_t dn, const gnutls_datum_t * data) { int result; char err[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; result = asn1_der_decoding((ASN1_TYPE *) & dn, data->data, data->size, err); if (result != ASN1_SUCCESS) { /* couldn't decode DER */ _gnutls_debug_log("ASN.1 Decoding error: %s\n", err); gnutls_assert(); return _gnutls_asn2err(result); } 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) { result = _gnutls_fbase64_decode(PEM_PKCS7, data->data, data->size, &_data); if (result <= 0) { gnutls_assert(); return 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; }
/* 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; }
/* * 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; }
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; }
/* 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; }
/* 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; }
int der_decode(const uint8_t *der, unsigned der_size, uint8_t *out, unsigned *out_size, char *realm, unsigned realm_size, int *error) { int ret, len; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; ret = asn1_create_element(_kkdcp_pkix1_asn, "KKDCP.KDC-PROXY-MESSAGE", &c2); if (ret != ASN1_SUCCESS) { *error = ret; return -1; } ret = asn1_der_decoding(&c2, der, der_size, NULL); if (ret != ASN1_SUCCESS) { *error = ret; ret = -1; goto cleanup; } len = *out_size; ret = asn1_read_value(c2, "kerb-message", out, &len); if (ret != ASN1_SUCCESS) { *error = ret; ret = -1; goto cleanup; } *out_size = len; len = realm_size; ret = asn1_read_value(c2, "target-domain", realm, &len); if (ret != ASN1_SUCCESS) { /* no realm was given */ realm[0] = 0; } ret = 0; cleanup: asn1_delete_structure(&c2); return ret; }
/** * asn1_copy_node: * @dst: Destination ASN1_TYPE node. * @dst_name: Field name in destination node. * @src: Source ASN1_TYPE node. * @src_name: Field name in source node. * * Create a deep copy of a ASN1_TYPE variable. * * Returns: Return %ASN1_SUCCESS on success. **/ asn1_retCode asn1_copy_node (ASN1_TYPE dst, const char *dst_name, ASN1_TYPE src, const char *src_name) { /* FIXME: rewrite using copy_structure(). * It seems quite hard to do. */ int result; ASN1_TYPE dst_node; void *data = NULL; int size = 0; result = asn1_der_coding (src, src_name, NULL, &size, NULL); if (result != ASN1_MEM_ERROR) return result; data = _asn1_malloc (size); if (data == NULL) return ASN1_MEM_ERROR; result = asn1_der_coding (src, src_name, data, &size, NULL); if (result != ASN1_SUCCESS) { _asn1_free (data); return result; } dst_node = asn1_find_node (dst, dst_name); if (dst_node == NULL) { _asn1_free (data); return ASN1_ELEMENT_NOT_FOUND; } result = asn1_der_decoding (&dst_node, data, size, NULL); _asn1_free (data); return result; }
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_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_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); }
/** * gnutls_x509_rdn_get: * @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 * * 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. * * 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(const gnutls_datum_t * idn, char *buf, size_t * buf_size) { int result; ASN1_TYPE dn = ASN1_TYPE_EMPTY; if (buf_size == 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, buf_size); asn1_delete_structure(&dn); 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; }
/* Decodes the SafeContents, and puts the output in * the given bag. */ int _pkcs12_decode_safe_contents (const gnutls_datum_t * content, gnutls_pkcs12_bag_t bag) { char oid[MAX_OID_SIZE], root[ASN1_MAX_NAME_SIZE]; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int len, result; int bag_type; gnutls_datum_t attr_val; int count = 0, i, attributes, j; size_t size; /* Step 1. Extract the SEQUENCE. */ if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents", &c2)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = asn1_der_decoding (&c2, content->data, content->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Count the number of bags */ result = asn1_number_of_elements (c2, "", &count); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } bag->bag_elements = MIN (MAX_BAG_ELEMENTS, count); for (i = 0; i < bag->bag_elements; i++) { snprintf (root, sizeof (root), "?%u.bagId", i + 1); len = sizeof (oid); result = asn1_read_value (c2, root, oid, &len); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Read the Bag type */ bag_type = oid2bag (oid); if (bag_type < 0) { gnutls_assert (); goto cleanup; } /* Read the Bag Value */ snprintf (root, sizeof (root), "?%u.bagValue", i + 1); result = _gnutls_x509_read_value (c2, root, &bag->element[i].data, 0); if (result < 0) { gnutls_assert (); goto cleanup; } if (bag_type == GNUTLS_BAG_CERTIFICATE || bag_type == GNUTLS_BAG_CRL || bag_type == GNUTLS_BAG_SECRET) { gnutls_datum_t tmp = bag->element[i].data; result = _pkcs12_decode_crt_bag (bag_type, &tmp, &bag->element[i].data); if (result < 0) { gnutls_assert (); goto cleanup; } _gnutls_free_datum (&tmp); } /* read the bag attributes */ snprintf (root, sizeof (root), "?%u.bagAttributes", i + 1); result = asn1_number_of_elements (c2, root, &attributes); if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if (attributes < 0) attributes = 1; if (result != ASN1_ELEMENT_NOT_FOUND) for (j = 0; j < attributes; j++) { snprintf (root, sizeof (root), "?%u.bagAttributes.?%u", i + 1, j + 1); result = _gnutls_x509_decode_and_read_attribute (c2, root, oid, sizeof (oid), &attr_val, 1, 0); if (result < 0) { gnutls_assert (); continue; /* continue in case we find some known attributes */ } if (strcmp (oid, KEY_ID_OID) == 0) { size = attr_val.size; result = _gnutls_x509_decode_octet_string (NULL, attr_val.data, size, attr_val.data, &size); attr_val.size = size; if (result < 0) { _gnutls_free_datum (&attr_val); gnutls_assert (); _gnutls_x509_log ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid); continue; } bag->element[i].local_key_id = attr_val; } else if (strcmp (oid, FRIENDLY_NAME_OID) == 0) { size = attr_val.size; result = _gnutls_x509_decode_octet_string ("BMPString", attr_val.data, size, attr_val.data, &size); attr_val.size = size; if (result < 0) { _gnutls_free_datum (&attr_val); gnutls_assert (); _gnutls_x509_log ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid); continue; } bag->element[i].friendly_name = ucs2_to_ascii (attr_val.data, attr_val.size); } else { _gnutls_free_datum (&attr_val); _gnutls_x509_log ("Unknown PKCS12 Bag Attribute OID '%s'\n", oid); } } bag->element[i].type = bag_type; } asn1_delete_structure (&c2); return 0; cleanup: if (c2) asn1_delete_structure (&c2); return result; }
static ASN1_TYPE decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) { int result; ASN1_TYPE dsa_asn; if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey", &dsa_asn)) != ASN1_SUCCESS) { gnutls_assert (); return NULL; } pkey->params.params_nr = 0; result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params.params[0])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params.params[1])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params.params[2])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params.params[3])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (dsa_asn, "priv", &pkey->params.params[4])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; return dsa_asn; error: asn1_delete_structure (&dsa_asn); gnutls_pk_params_release(&pkey->params); return NULL; }
/* Converts an ECC key to * an internal structure (gnutls_private_key) */ ASN1_TYPE _gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) { int ret; ASN1_TYPE pkey_asn; unsigned int version; char oid[MAX_OID_SIZE]; int oid_size; gnutls_datum out; gnutls_pk_params_init(&pkey->params); if ((ret = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.ECPrivateKey", &pkey_asn)) != ASN1_SUCCESS) { gnutls_assert (); return NULL; } ret = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL); if (ret != ASN1_SUCCESS) { gnutls_assert (); goto error; } ret = _gnutls_x509_read_uint (pkey_asn, "Version", &version); if (ret < 0) { gnutls_assert(); goto error; } if (version != 1) { _gnutls_debug_log("ECC private key version %u is not supported\n", version); gnutls_assert(); goto error; } /* read the curve */ oid_size = sizeof(oid); ret = asn1_read_value(pkey_asn, "parameters.namedCurve", oid, &oid_size); if (ret != ASN1_SUCCESS) { gnutls_assert (); goto error; } pkey->params.flags = _gnutls_oid_to_ecc_curve(oid); if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID) { _gnutls_debug_log("Curve %s is not supported\n", oid); gnutls_assert(); goto error; } ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params); if (ret < 0) { gnutls_assert(); goto error; } /* read the public key */ ret = _gnutls_x509_read_value(pkey_asn, "publicKey", &out, 2); if (ret < 0) { gnutls_assert(); goto error; } ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[ECC_X], &pkey->params.params[ECC_Y]); _gnutls_free_datum(&out); if (ret < 0) { gnutls_assert(); goto error; } pkey->params.params_nr += 2; /* read the private key */ ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[ECC_K]); if (ret < 0) { gnutls_assert(); goto error; } pkey->params.params_nr ++; return pkey_asn; error: asn1_delete_structure (&pkey_asn); gnutls_pk_params_release (&pkey->params); return NULL; }
/* Converts an RSA PKCS#1 key to * an internal structure (gnutls_private_key) */ ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) { int result; ASN1_TYPE pkey_asn; gnutls_pk_params_init(&pkey->params); if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", &pkey_asn)) != ASN1_SUCCESS) { gnutls_assert (); return NULL; } result = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "modulus", &pkey->params.params[0])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "publicExponent", &pkey->params.params[1])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "privateExponent", &pkey->params.params[2])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "prime1", &pkey->params.params[3])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "prime2", &pkey->params.params[4])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient", &pkey->params.params[5])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1", &pkey->params.params[6])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "exponent2", &pkey->params.params[7])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params); if (result < 0) { gnutls_assert (); goto error; } pkey->params.params_nr = RSA_PRIVATE_PARAMS; return pkey_asn; error: asn1_delete_structure (&pkey_asn); gnutls_pk_params_release (&pkey->params); return NULL; }
int main (int argc, char *argv[]) { FILE *fpin, *fpout; const char *fileNameIn; const char *fileNameOut; unsigned char buffer[MAX_LENGTH_INT]; unsigned char newBuffer[2*MAX_LENGTH_INT]; char params[MAX_LENGTH_CMD]; char str[MAX_LENGTH_VAR]; // Number of polynomial or integer of a polynomial char n[MAX_LENGTH_VAR]; // Number of variables as a string char o[MAX_LENGTH_VAR]; // Number of polynomials as a string int nn; // Number of variables as an integer int oo; // Number of polynomials as an integer int i, j; int result, der_len; unsigned char der[MAX_DER_SIZE], ch[1]; /******* Define input and output files *******/ if (argc < 3) { printf("\nusage: %s ASN1BinaryFile PublicKeyIntFile\n\n", argv[0]); exit(1); } else { fileNameIn = argv[1]; fileNameOut = argv[2]; fpin = fopen(fileNameIn, "rb"); if (!fpin) { printf("\nError openning file: %s\n\n", fileNameIn); exit(1); } fpout = fopen(fileNameOut, "w"); if (!fpout) { fclose(fpin); printf("\nError openning file: %s\n\n", fileNameOut); exit(1); } } printf("\nDecoding an ASN.1 file (%s), into a text file (%s)\n", fileNameIn, fileNameOut); /******* ASN.1 initialization *******/ ASN1_TYPE PK_def = ASN1_TYPE_EMPTY; ASN1_TYPE PK_dec = ASN1_TYPE_EMPTY; char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; // Creates definition structures needed to manage the ASN.1 definitions result = asn1_array2tree(pkInt_asn1_tab, &PK_def, errorDescription); if (result != ASN1_SUCCESS) { asn1_perror(result); printf ("%s\n", errorDescription); exit (1); } // Creates a structure of type "PKInt" (from *.asn definition file) result = asn1_create_element(PK_def, "PKInt.PublicKey", &PK_dec); if ( result != ASN1_SUCCESS ) { printf("\nCould not create a new element to DECODE: %d\n", result); exit(1); } /******* Read data from input file *******/ der_len = i = 0; while ( 1 == fread(ch, 1, 1, fpin) ) { der[i] = ch[0]; i++; der_len++; } result = asn1_der_decoding(&PK_dec, der, der_len, errorDescription); if ( result != ASN1_SUCCESS ) { printf("\nCould not make a DER decoding: %d\n", result); printf("Error description: %s\n", errorDescription); asn1_perror(result); exit(2); } /*printf("------------DEC-----------------\n"); asn1_print_structure(stdout, PK_dec, "", ASN1_PRINT_ALL); printf("--------------------------------\n");*/ clrBuff(buffer, MAX_LENGTH_INT); // Necesary because asn1 functions just put data in buffer // without terminating it with 0x0!!! der_len = MAX_LENGTH_INT; result = asn1_read_value(PK_dec, "noVars", buffer, &der_len); if ( result != ASN1_SUCCESS ) { printf("\nCould not make a DER decoding (noVars): %d\n", result); printf("Error description: %s\n", errorDescription); exit(1); } nn = atoi(buffer); clrBuff(buffer, MAX_LENGTH_INT); der_len = MAX_LENGTH_INT; result = asn1_read_value(PK_dec, "noPoly", buffer, &der_len); if ( result != ASN1_SUCCESS ) { printf("\nCould not make a DER decoding (noPoly): %d\n", result); printf("Error description: %s\n", errorDescription); exit(1); } oo = atoi(buffer); printf("Number of variables: %d\nNumber of polynomials: %d\n", nn, oo); /******* Write 'n' and 'o' to output file ******/ sprintf(str, "%d", nn); fprintf(fpout, "%s\n", str); sprintf(str, "%d", oo); fprintf(fpout, "%s\n", str); // ******* Read all integers representing the polynomials ******* nn = nn + 2; // +2 because of linear terms vector and constant term for ( i=0; i<oo; i++ ) { for ( j=0; j<nn; j++) { der_len = MAX_LENGTH_INT; sprintf(o, "%d", i+1); // Number of polynomial as string in 'o' sprintf(n, "%d", j+1); // Number of integer as string in 'n' strcpy(params, "polys.?"); strcat(params, o); strcat(params, ".intData.?"); strcat(params, n); clrBuff(buffer, MAX_LENGTH_INT); result = asn1_read_value(PK_dec, params, buffer, &der_len); /******* Write that integer (as a string) to output file *******/ fprintf(fpout, "%s", buffer); fprintf(fpout, " "); if ( j == nn - 1 ) fprintf(fpout, "\n"); if ( result != ASN1_SUCCESS ) { asn1_perror(result); printf("Could not write value in 'intData', i: %d\n", i); exit(4); } } } printf("...Done!\n\n"); /******* Closing program *******/ asn1_delete_structure(&PK_dec); asn1_delete_structure(&PK_def); fclose(fpin); fclose(fpout); return 0; }