/** * 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; }
/* 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; }
/* 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; }
int _gnutls_encode_ber_rs(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 = _gnutls_x509_write_int(sig, "r", r, 1); if (result < 0) { gnutls_assert(); asn1_delete_structure(&sig); return result; } result = _gnutls_x509_write_int(sig, "s", s, 1); if (result < 0) { gnutls_assert(); asn1_delete_structure(&sig); return result; } result = _gnutls_x509_der_encode(sig, "", sig_value, 0); asn1_delete_structure(&sig); if (result < 0) return gnutls_assert_val(result); return 0; }
/** * gnutls_x509_privkey_deinit - This function deinitializes memory used by a gnutls_x509_privkey_t structure * @key: The structure to be initialized * * This function will deinitialize a private key structure. * **/ void gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key) { int i; if (!key) return; for (i = 0; i < key->params_size; i++) { _gnutls_mpi_release (&key->params[i]); } asn1_delete_structure (&key->key); gnutls_free (key); }
/** * gnutls_x509_crl_get_authority_key_gn_serial: * @crl: should contain a #gnutls_x509_crl_t structure * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.) * @alt: is the place where the alternative name will be copied to * @alt_size: holds the size of alt. * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t). * @serial: buffer to store the serial number (may be null) * @serial_size: Holds the size of the serial field (may be null) * @critical: will be non-zero if the extension is marked as critical (may be null) * * This function will return the X.509 authority key * identifier when stored as a general name (authorityCertIssuer) * and serial number. * * Because more than one general names might be stored * @seq can be used as a counter to request them all until * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. * * Returns: Returns 0 on success, or an error code. * * Since: 3.0 **/ int gnutls_x509_crl_get_authority_key_gn_serial(gnutls_x509_crl_t crl, unsigned int seq, void *alt, size_t * alt_size, unsigned int *alt_type, void *serial, size_t * serial_size, unsigned int *critical) { int ret, result, len; ASN1_TYPE c2; ret = _get_authority_key_id(crl, &c2, critical); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_parse_general_name(c2, "authorityCertIssuer", seq, alt, alt_size, alt_type, 0); if (ret < 0) { ret = gnutls_assert_val(ret); goto fail; } if (serial) { len = *serial_size; result = asn1_read_value(c2, "authorityCertSerialNumber", serial, &len); *serial_size = len; if (result < 0) { ret = _gnutls_asn2err(result); goto fail; } } ret = 0; fail: asn1_delete_structure(&c2); return ret; }
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; }
/* * This function writes the public parameters for DSS keys. * Needs 1 parameter (y). * * Allocates the space used to store the DER data. */ int _gnutls_x509_write_dsa_public_key (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 < 3) { gnutls_assert (); result = GNUTLS_E_INVALID_REQUEST; goto cleanup; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = _gnutls_x509_write_int (spk, "", params[3], 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; }
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; }
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; }
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; }
/** * gnutls_x509_privkey_fix: * @key: Holds the key * * This function will recalculate the secondary parameters in a key. * In RSA keys, this can be the coefficient and exponent1,2. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_fix (gnutls_x509_privkey_t key) { int ret; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } asn1_delete_structure (&key->key); ret = _gnutls_asn1_encode_privkey (key->pk_algorithm, &key->key, &key->params); if (ret < 0) { gnutls_assert (); return ret; } return 0; }
static bool prepare_pem_contents (p11_enumerate *ex, p11_buffer *buffer) { char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; unsigned char *der; node_asn *asn; size_t offset; int ret; int len; p11_buffer_add (buffer, ex->cert_der, ex->cert_len); asn = p11_asn1_create (ex->asn1_defs, "OPENSSL.CertAux"); return_val_if_fail (asn != NULL, false); if (!write_trust_and_rejects (ex, asn) || !write_alias (ex, asn) || !write_keyid (ex, asn) || !write_other (ex, asn)) return_val_if_reached (false); len = 0; offset = buffer->len; ret = asn1_der_coding (asn, "", NULL, &len, message); return_val_if_fail (ret == ASN1_MEM_ERROR, false); der = p11_buffer_append (buffer, len); return_val_if_fail (der != NULL, false); ret = asn1_der_coding (asn, "", der, &len, message); return_val_if_fail (ret == ASN1_SUCCESS, false); buffer->len = offset + len; asn1_delete_structure (&asn); return true; }
/** * gnutls_x509_privkey_fix - This function will recalculate some parameters of the key. * @key: Holds the key * * This function will recalculate the secondary parameters in a key. * In RSA keys, this can be the coefficient and exponent1,2. * * Return value: In case of failure a negative value will be * returned, and 0 on success. * **/ int gnutls_x509_privkey_fix (gnutls_x509_privkey_t key) { int ret; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } if (!key->crippled) asn1_delete_structure (&key->key); switch (key->pk_algorithm) { case GNUTLS_PK_DSA: ret = _encode_dsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); return ret; } break; case GNUTLS_PK_RSA: ret = _encode_rsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); return ret; } break; default: gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } return 0; }
int main (int argc, char *argv[]) { int result, der_len; unsigned char der[1024]; ASN1_TYPE PKIX1Implicit88 = ASN1_TYPE_EMPTY; char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; if (1) result = asn1_array2tree (pkix_asn1_tab, &PKIX1Implicit88, errorDescription); else result = asn1_parser2tree ("pkix.asn", &PKIX1Implicit88, errorDescription); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("%s", errorDescription); exit (1); } /* Use the following 3 lines to visit the PKIX1Implicit structures */ /* printf("-----------------\n"); asn1_visit_tree(PKIX1Implicit88,"PKIX1Implicit88"); printf("-----------------\n"); */ der_len = 1024; create_certificate (PKIX1Implicit88, der, &der_len); get_certificate (PKIX1Implicit88, der, der_len); /* Clear the "PKIX1Implicit88" structures */ asn1_delete_structure (&PKIX1Implicit88); return 0; }
int der_encode_inplace(uint8_t *raw, unsigned *raw_size, unsigned max_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_write_value(c2, "kerb-message", raw, *raw_size); if (ret != ASN1_SUCCESS) { *error = ret; ret = -1; goto cleanup; } asn1_write_value(c2, "target-domain", NULL, 0); asn1_write_value(c2, "dclocator-hint", NULL, 0); len = max_size; ret = asn1_der_coding(c2, "", raw, &len, NULL); if (ret != ASN1_SUCCESS) { *error = ret; ret = -1; goto cleanup; } *raw_size = len; ret = 0; cleanup: asn1_delete_structure(&c2); return ret; }
/* 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; }
/* Encodes the bag into a SafeContents structure, and puts the output in * the given datum. Enc is set to non zero if the data are encrypted; */ int _pkcs12_encode_safe_contents (gnutls_pkcs12_bag_t bag, ASN1_TYPE * contents, int *enc) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result; int i; const char *oid; if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED && enc) { *enc = 1; return 0; /* ENCRYPTED BAG, do nothing. */ } else if (enc) *enc = 0; /* Step 1. Create 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; } for (i = 0; i < bag->bag_elements; i++) { oid = bag_to_oid (bag->element[i].type); if (oid == NULL) { gnutls_assert (); continue; } result = asn1_write_value (c2, "", "NEW", 1); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Copy the bag type. */ result = asn1_write_value (c2, "?LAST.bagId", oid, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Set empty attributes */ result = write_attributes (bag, i, c2, "?LAST.bagAttributes"); if (result < 0) { gnutls_assert (); goto cleanup; } /* Copy the Bag Value */ if (bag->element[i].type == GNUTLS_BAG_CERTIFICATE || bag->element[i].type == GNUTLS_BAG_SECRET || bag->element[i].type == GNUTLS_BAG_CRL) { gnutls_datum_t tmp; /* in that case encode it to a CertBag or * a CrlBag. */ result = _pkcs12_encode_crt_bag (bag->element[i].type, &bag->element[i].data, &tmp); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_x509_write_value (c2, "?LAST.bagValue", &tmp, 0); _gnutls_free_datum (&tmp); } else { result = _gnutls_x509_write_value (c2, "?LAST.bagValue", &bag->element[i].data, 0); } if (result < 0) { gnutls_assert (); goto cleanup; } } /* Encode the data and copy them into the datum */ *contents = 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; }
/* Writes the digest information and the digest in a DER encoded * structure. The digest info is allocated and stored into the info structure. */ static int encode_ber_digest_info (gnutls_digest_algorithm_t hash, const gnutls_datum_t * digest, gnutls_datum_t * info) { ASN1_TYPE dinfo = ASN1_TYPE_EMPTY; int result; const char *algo; algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash); if (algo == NULL) { gnutls_assert (); _gnutls_x509_log ("Hash algorithm: %d\n", hash); return GNUTLS_E_UNKNOWN_PK_ALGORITHM; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DigestInfo", &dinfo)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } /* Write an ASN.1 NULL in the parameters field. This matches RFC 3279 and RFC 4055, although is arguable incorrect from a historic perspective (see those documents for more information). Regardless of what is correct, this appears to be what most implementations do. */ result = asn1_write_value (dinfo, "digestAlgorithm.parameters", ASN1_NULL, ASN1_NULL_SIZE); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } result = asn1_write_value (dinfo, "digest", digest->data, digest->size); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } info->size = 0; asn1_der_coding (dinfo, "", NULL, &info->size, NULL); info->data = gnutls_malloc (info->size); if (info->data == NULL) { gnutls_assert (); asn1_delete_structure (&dinfo); return GNUTLS_E_MEMORY_ERROR; } result = asn1_der_coding (dinfo, "", info->data, &info->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } asn1_delete_structure (&dinfo); return 0; }
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; }
int main (int argc, char** argv) { int result = 0; asn1_node definitions = NULL, node1 = NULL, node2 = NULL; char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; const char *choicefile = getenv ("ASN1CHOICE"); char data[1024]; int data_size = sizeof (data); if (!choicefile) choicefile = "pkix.asn"; /* Encode */ result = asn1_parser2tree (choicefile, &definitions, errorDescription); if (result != ASN1_SUCCESS) { printf ("error in %d\n", __LINE__); exit (1); } result = asn1_create_element (definitions, "TEST.Choice0", &node1); if (result != ASN1_SUCCESS) { printf ("error in %d\n", __LINE__); exit (1); } result = asn1_write_value (node1, "", "choice1", 1); if (result != ASN1_SUCCESS) { printf ("error in %d\n", __LINE__); exit (1); } result = asn1_write_value (node1, "choice1", "choice2", 1); if (result != ASN1_SUCCESS) { printf ("error in %d\n", __LINE__); exit (1); } result = asn1_write_value (node1, "choice1.choice2", "int1", 1); if (result != ASN1_SUCCESS) { printf ("error in %d\n", __LINE__); exit (1); } result = asn1_write_value (node1, "choice1.choice2.int1", "1234", 0); if (result != ASN1_SUCCESS) { printf ("error in %d\n", __LINE__); exit (1); } result = asn1_der_coding (node1, "", data, &data_size, errorDescription); if (result != ASN1_SUCCESS) { printf ("error in %d\n", __LINE__); exit (1); } asn1_delete_structure (&node1); /* Decode */ result = asn1_create_element (definitions, "TEST.Choice0", &node2); if (result != ASN1_SUCCESS) { printf ("error in %d\n", __LINE__); exit (1); } #if 0 printf ("der:"); for (i = 0; i < data_size; i++) printf ("%.2x ", (unsigned char) (data[i])); printf ("\n"); #endif result = asn1_der_decoding (&node2, data, data_size, errorDescription); if (result != ASN1_SUCCESS) { printf ("error in %d\n", __LINE__); exit (1); } asn1_delete_structure (&node2); asn1_delete_structure (&definitions); return 0; }
/* Encodes the RSA parameters into an ASN.1 RSA private key structure. */ static int _encode_rsa (ASN1_TYPE * c2, mpi_t * params) { int result, i; size_t size[8], total; opaque *m_data, *pube_data, *prie_data; opaque *p1_data, *p2_data, *u_data, *exp1_data, *exp2_data; opaque *all_data = NULL, *p; mpi_t exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL, u = NULL; opaque null = '\0'; /* Read all the sizes */ total = 0; for (i = 0; i < 5; i++) { _gnutls_mpi_print_lz (NULL, &size[i], params[i]); total += size[i]; } /* Now generate exp1 and exp2 */ exp1 = _gnutls_mpi_salloc_like (params[0]); /* like modulus */ if (exp1 == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } exp2 = _gnutls_mpi_salloc_like (params[0]); if (exp2 == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } q1 = _gnutls_mpi_salloc_like (params[4]); if (q1 == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } p1 = _gnutls_mpi_salloc_like (params[3]); if (p1 == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } u = _gnutls_mpi_salloc_like (params[3]); if (u == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } _gnutls_mpi_invm (u, params[4], params[3]); /* inverse of q mod p */ _gnutls_mpi_print_lz (NULL, &size[5], u); total += size[5]; _gnutls_mpi_sub_ui (p1, params[3], 1); _gnutls_mpi_sub_ui (q1, params[4], 1); _gnutls_mpi_mod (exp1, params[2], p1); _gnutls_mpi_mod (exp2, params[2], q1); /* calculate exp's size */ _gnutls_mpi_print_lz (NULL, &size[6], exp1); total += size[6]; _gnutls_mpi_print_lz (NULL, &size[7], exp2); total += size[7]; /* Encoding phase. * allocate data enough to hold everything */ all_data = gnutls_secure_malloc (total); if (all_data == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } p = all_data; m_data = p; p += size[0]; pube_data = p; p += size[1]; prie_data = p; p += size[2]; p1_data = p; p += size[3]; p2_data = p; p += size[4]; u_data = p; p += size[5]; exp1_data = p; p += size[6]; exp2_data = p; _gnutls_mpi_print_lz (m_data, &size[0], params[0]); _gnutls_mpi_print_lz (pube_data, &size[1], params[1]); _gnutls_mpi_print_lz (prie_data, &size[2], params[2]); _gnutls_mpi_print_lz (p1_data, &size[3], params[3]); _gnutls_mpi_print_lz (p2_data, &size[4], params[4]); _gnutls_mpi_print_lz (u_data, &size[5], u); _gnutls_mpi_print_lz (exp1_data, &size[6], exp1); _gnutls_mpi_print_lz (exp2_data, &size[7], exp2); /* Ok. Now we have the data. Create the asn1 structures */ if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", c2)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Write PRIME */ if ((result = asn1_write_value (*c2, "modulus", m_data, size[0])) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "publicExponent", pube_data, size[1])) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "privateExponent", prie_data, size[2])) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "prime1", p1_data, size[3])) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "prime2", p2_data, size[4])) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "exponent1", exp1_data, size[6])) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "exponent2", exp2_data, size[7])) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "coefficient", u_data, size[5])) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } _gnutls_mpi_release (&exp1); _gnutls_mpi_release (&exp2); _gnutls_mpi_release (&q1); _gnutls_mpi_release (&p1); _gnutls_mpi_release (&u); gnutls_free (all_data); if ((result = asn1_write_value (*c2, "otherPrimeInfos", NULL, 0)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } return 0; cleanup: _gnutls_mpi_release (&u); _gnutls_mpi_release (&exp1); _gnutls_mpi_release (&exp2); _gnutls_mpi_release (&q1); _gnutls_mpi_release (&p1); asn1_delete_structure (c2); gnutls_free (all_data); return result; }
/** * gnutls_pkcs12_get_bag: * @pkcs12: should contain a gnutls_pkcs12_t structure * @indx: contains the index of the bag to extract * @bag: An initialized bag, where the contents of the bag will be copied * * This function will return a Bag from the PKCS12 structure. * * After the last Bag has been read * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_pkcs12_get_bag (gnutls_pkcs12_t pkcs12, int indx, gnutls_pkcs12_bag_t bag) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result, len; char root2[ASN1_MAX_NAME_SIZE]; char oid[MAX_OID_SIZE]; if (pkcs12 == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* Step 1. decode the data. */ result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL); if (result < 0) { gnutls_assert (); return result; } /* Step 2. Parse the AuthenticatedSafe */ snprintf (root2, sizeof (root2), "?%u.contentType", indx + 1); len = sizeof (oid) - 1; result = asn1_read_value (c2, root2, oid, &len); if (result == ASN1_ELEMENT_NOT_FOUND) { result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; goto cleanup; } if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Not encrypted Bag */ snprintf (root2, sizeof (root2), "?%u.content", indx + 1); if (strcmp (oid, DATA_OID) == 0) { result = _parse_safe_contents (c2, root2, bag); goto cleanup; } /* ENC_DATA_OID needs decryption */ bag->element[0].type = GNUTLS_BAG_ENCRYPTED; bag->bag_elements = 1; result = _gnutls_x509_read_value (c2, root2, &bag->element[0].data, 0); if (result < 0) { gnutls_assert (); goto cleanup; } result = 0; cleanup: if (c2) asn1_delete_structure (&c2); return result; }
/** * gnutls_pkcs12_set_bag: * @pkcs12: should contain a gnutls_pkcs12_t structure * @bag: An initialized bag * * This function will insert a Bag into the PKCS12 structure. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_pkcs12_set_bag (gnutls_pkcs12_t pkcs12, gnutls_pkcs12_bag_t bag) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY; int result; int enc = 0, dum = 1; char null; if (pkcs12 == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* Step 1. Check if the pkcs12 structure is empty. In that * case generate an empty PFX. */ result = asn1_read_value (pkcs12->pkcs12, "authSafe.content", &null, &dum); if (result == ASN1_VALUE_NOT_FOUND) { result = create_empty_pfx (pkcs12->pkcs12); if (result < 0) { gnutls_assert (); return result; } } /* Step 2. decode the authenticatedSafe. */ result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL); if (result < 0) { gnutls_assert (); return result; } /* Step 3. Encode the bag elements into a SafeContents * structure. */ result = _pkcs12_encode_safe_contents (bag, &safe_cont, &enc); if (result < 0) { gnutls_assert (); return result; } /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe * structure. */ result = asn1_write_value (c2, "", "NEW", 1); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if (enc) result = asn1_write_value (c2, "?LAST.contentType", ENC_DATA_OID, 1); else result = asn1_write_value (c2, "?LAST.contentType", DATA_OID, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if (enc) { /* Encrypted packets are written directly. */ result = asn1_write_value (c2, "?LAST.content", bag->element[0].data.data, bag->element[0].data.size); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } } else { result = _gnutls_x509_der_encode_and_copy (safe_cont, "", c2, "?LAST.content", 1); if (result < 0) { gnutls_assert (); goto cleanup; } } asn1_delete_structure (&safe_cont); /* Step 5. Reencode and copy the AuthenticatedSafe into the pkcs12 * structure. */ result = _gnutls_x509_der_encode_and_copy (c2, "", pkcs12->pkcs12, "authSafe.content", 1); if (result < 0) { gnutls_assert (); goto cleanup; } asn1_delete_structure (&c2); return 0; cleanup: asn1_delete_structure (&c2); asn1_delete_structure (&safe_cont); 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; } if ((sizeof (pkey->params) / sizeof (mpi_t)) < DSA_PRIVATE_PARAMS) { gnutls_assert (); /* internal error. Increase the mpi_ts in params */ return NULL; } 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[0])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params[1])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params[2])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params[3])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (dsa_asn, "priv", &pkey->params[4])) < 0) { gnutls_assert (); goto error; } pkey->params_size = 5; return dsa_asn; error: asn1_delete_structure (&dsa_asn); _gnutls_mpi_release (&pkey->params[0]); _gnutls_mpi_release (&pkey->params[1]); _gnutls_mpi_release (&pkey->params[2]); _gnutls_mpi_release (&pkey->params[3]); _gnutls_mpi_release (&pkey->params[4]); return NULL; }