int _gnutls_x509_get_raw_field2(ASN1_TYPE c2, gnutls_datum_t * raw, const char *whom, gnutls_datum_t * dn) { int result, len1; int start1, end1; result = asn1_der_decoding_startEnd(c2, raw->data, raw->size, whom, &start1, &end1); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } len1 = end1 - start1 + 1; dn->data = &raw->data[start1]; dn->size = len1; result = 0; cleanup: return result; }
/* Reads the DER signed data from the certificate and allocates space and * returns them into signed_data. */ int _gnutls_x509_get_signed_data(ASN1_TYPE src, const gnutls_datum *der, const char *src_name, gnutls_datum_t * signed_data) { int start, end, result; if (der == NULL || der->size == 0) { return _gnutls_x509_der_encode(src, src_name, signed_data, 0); } /* Get the signed data */ result = asn1_der_decoding_startEnd(src, der->data, der->size, src_name, &start, &end); if (result != ASN1_SUCCESS) { result = _gnutls_asn2err(result); gnutls_assert(); goto cleanup; } result = _gnutls_set_datum(signed_data, &der->data[start], end - start + 1); if (result < 0) { gnutls_assert(); goto cleanup; } result = 0; cleanup: 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_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; }
/* Reads the DER signed data from the certificate and allocates space and * returns them into signed_data. */ int _gnutls_x509_get_signed_data(ASN1_TYPE src, const gnutls_datum *_der, const char *src_name, gnutls_datum_t * signed_data) { int start, end, result; gnutls_datum_t der; unsigned need_free = 0; if (_der == NULL || _der->size == 0) { result = _gnutls_x509_der_encode(src, "", &der, 0); if (result < 0) { gnutls_assert(); return result; } need_free = 1; } else { der.data = _der->data; der.size = _der->size; } /* Get the signed data */ result = asn1_der_decoding_startEnd(src, der.data, der.size, src_name, &start, &end); if (result != ASN1_SUCCESS) { result = _gnutls_asn2err(result); gnutls_assert(); goto cleanup; } result = _gnutls_set_datum(signed_data, &der.data[start], end - start + 1); if (result < 0) { gnutls_assert(); goto cleanup; } result = 0; cleanup: if (need_free != 0) _gnutls_free_datum(&der); return result; }
/* Reads the DER signed data from the certificate and allocates space and * returns them into signed_data. */ int _gnutls_x509_get_signed_data (ASN1_TYPE src, const char *src_name, gnutls_datum_t * signed_data) { gnutls_datum_t der; int start, end, result; result = _gnutls_x509_der_encode (src, "", &der, 0); if (result < 0) { gnutls_assert (); return result; } /* Get the signed data */ result = asn1_der_decoding_startEnd (src, der.data, der.size, src_name, &start, &end); if (result != ASN1_SUCCESS) { result = _gnutls_asn2err (result); gnutls_assert (); goto cleanup; } result = _gnutls_set_datum (signed_data, &der.data[start], end - start + 1); if (result < 0) { gnutls_assert (); goto cleanup; } result = 0; cleanup: _gnutls_free_datum (&der); return result; }
static bool load_attached_extension (p11_dict *attached, p11_dict *asn1_defs, const unsigned char *der, size_t len) { char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; node_asn *ext; char *oid; int length; int start; int end; int ret; ext = p11_asn1_decode (asn1_defs, "PKIX1.Extension", der, len, message); if (ext == NULL) { p11_message ("couldn't parse attached certificate extension: %s", message); return false; } ret = asn1_der_decoding_startEnd (ext, der, len, "extnID", &start, &end); return_val_if_fail (ret == ASN1_SUCCESS, false); /* Make sure it's a straightforward oid with certain assumptions */ length = (end - start) + 1; if (!p11_oid_simple (der + start, length)) { p11_debug ("strange complex certificate extension object id"); return false; } oid = memdup (der + start, length); return_val_if_fail (oid != NULL, false); if (!p11_dict_set (attached, oid, ext)) return_val_if_reached (false); return true; }
/*- * _gnutls_x509_crl_get_raw_issuer_dn - This function returns the issuer's DN DER encoded * @crl: should contain a gnutls_x509_crl_t structure * @dn: will hold the starting point of the DN * * This function will return a pointer to the DER encoded DN structure and * the length. * * Returns a negative value on error, and zero on success. * -*/ int _gnutls_x509_crl_get_raw_issuer_dn (gnutls_x509_crl_t crl, gnutls_datum_t * dn) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result, len1; int start1, end1; gnutls_datum_t crl_signed_data; if (crl == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* get the issuer of 'crl' */ if ((result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertList", &c2)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data); if (result < 0) { gnutls_assert (); goto cleanup; } result = asn1_der_decoding (&c2, crl_signed_data.data, crl_signed_data.size, NULL); if (result != ASN1_SUCCESS) { /* couldn't decode DER */ gnutls_assert (); asn1_delete_structure (&c2); result = _gnutls_asn2err (result); goto cleanup; } result = asn1_der_decoding_startEnd (c2, crl_signed_data.data, crl_signed_data.size, "issuer", &start1, &end1); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } len1 = end1 - start1 + 1; _gnutls_set_datum (dn, &crl_signed_data.data[start1], len1); result = 0; cleanup: asn1_delete_structure (&c2); _gnutls_free_datum (&crl_signed_data); return result; }
int main (int argc, char *argv[]) { int result; char buffer[5 * 1024]; char buffer2[5 * 1024]; asn1_node definitions = NULL; asn1_node asn1_element = NULL, cpy_node = NULL; char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; FILE *out, *fd; int start, end; ssize_t size; int size2; const char *treefile = getenv ("ASN1PKIX"); const char *derfile = getenv ("ASN1CRLDER"); int verbose = 0; if (argc > 1) verbose = 1; if (!treefile) treefile = "pkix.asn"; if (!derfile) derfile = "crl.der"; if (verbose) { printf ("\n\n/****************************************/\n"); printf ("/* Test sequence : Test_indefinite */\n"); printf ("/****************************************/\n\n"); printf ("ASN1TREE: %s\n", treefile); } /* Check version */ if (asn1_check_version ("0.3.3") == NULL) printf ("\nLibrary version check ERROR:\n actual version: %s\n\n", asn1_check_version (NULL)); result = asn1_parser2tree (treefile, &definitions, errorDescription); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("ErrorDescription = %s\n\n", errorDescription); exit (1); } out = stdout; fd = fopen (derfile, "rb"); if (fd == NULL) { printf ("Cannot read file %s\n", derfile); exit (1); } size = fread (buffer, 1, sizeof (buffer), fd); if (size <= 0) { printf ("Cannot read from file %s\n", derfile); exit (1); } fclose (fd); result = asn1_create_element (definitions, "PKIX1.CertificateList", &asn1_element); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("Cannot create CRL element\n"); exit (1); } result = asn1_der_decoding (&asn1_element, buffer, size, errorDescription); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("Cannot decode DER data (size %ld)\n", (long) size); exit (1); } /* test asn1_copy_node */ result = asn1_create_element (definitions, "PKIX1.CertificateList", &cpy_node); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("Cannot create CRL element\n"); exit (1); } result = asn1_copy_node(cpy_node, "", asn1_element, ""); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("Cannot copy node\n"); exit (1); } /* test whether the copied node encodes the same */ size2 = sizeof(buffer2); result = asn1_der_coding (cpy_node, "", buffer2, &size2, NULL); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("Cannot encode data (size %ld)\n", (long) size); exit (1); } if (size2 != size || memcmp(buffer, buffer2, size) != 0) { printf("DER encoded data differ!\n"); exit(1); } asn1_delete_structure (&cpy_node); /* Test asn1_dup_node */ cpy_node = asn1_dup_node(asn1_element, ""); if (cpy_node == NULL) { printf ("Cannot copy node (dup_node)\n"); exit (1); } /* test whether the copied node encodes the same */ size2 = sizeof(buffer2); result = asn1_der_coding (cpy_node, "", buffer2, &size2, NULL); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("Cannot encode data (size %ld)\n", (long) size); exit (1); } if (size2 != size || memcmp(buffer, buffer2, size) != 0) { printf("DER encoded data differ!\n"); exit(1); } result = asn1_der_decoding_startEnd (asn1_element, buffer, size, "tbsCertList.issuer", &start, &end); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("Cannot find start End\n"); exit (1); } if (start != 24 && end != 291) { printf("Error in start and end values for issuer. Have: %d..%d\n", start, end); exit(1); } result = asn1_der_decoding_startEnd (asn1_element, buffer, size, "signature", &start, &end); if (result != ASN1_SUCCESS) { asn1_perror (result); printf ("Cannot find start End\n"); exit (1); } if (start != 372 && end != 503) { printf("Error in start and end values for signature. Have: %d..%d\n", start, end); exit(1); } /* Clear the definition structures */ asn1_delete_structure (&asn1_element); asn1_delete_structure (&cpy_node); asn1_delete_structure (&definitions); if (out != stdout) fclose (out); exit (0); }
static int pkcs8_key_info(const gnutls_datum_t * raw_key, const struct pkcs_cipher_schema_st **p, struct pbkdf2_params *kdf_params, char **oid) { int result, len; char enc_oid[MAX_OID_SIZE*2]; int params_start, params_end, params_len; struct pbe_enc_params enc_params; schema_id schema; ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY; memset(&enc_params, 0, sizeof(enc_params)); result = check_for_decrypted(raw_key); if (result == 0) return GNUTLS_E_INVALID_REQUEST; 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; } /* Check the encryption schema OID */ len = sizeof(enc_oid); result = asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm", enc_oid, &len); if (result != ASN1_SUCCESS) { gnutls_assert(); goto error; } if (oid) { *oid = gnutls_strdup(enc_oid); } if ((result = _gnutls_check_pkcs_cipher_schema(enc_oid)) < 0) { gnutls_assert(); goto error; } schema = result; /* Get the DER encoding of the parameters. */ result = asn1_der_decoding_startEnd(pkcs8_asn, raw_key->data, raw_key->size, "encryptionAlgorithm.parameters", ¶ms_start, ¶ms_end); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } params_len = params_end - params_start + 1; result = _gnutls_read_pkcs_schema_params(&schema, NULL, &raw_key->data[params_start], params_len, kdf_params, &enc_params); if (result < 0) { gnutls_assert(); if (oid && enc_params.pbes2_oid[0] != 0) { snprintf(enc_oid, sizeof(enc_oid), "%s/%s", *oid, enc_params.pbes2_oid); gnutls_free(*oid); *oid = gnutls_strdup(enc_oid); } goto error; } *p = _gnutls_pkcs_schema_get(schema); if (*p == NULL) { gnutls_assert(); result = GNUTLS_E_UNKNOWN_CIPHER_TYPE; goto error; } result = 0; error: asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE); return result; }
static int pkcs8_key_decrypt(const gnutls_datum_t * raw_key, ASN1_TYPE pkcs8_asn, const char *password, gnutls_x509_privkey_t pkey) { int result, len; char enc_oid[MAX_OID_SIZE]; gnutls_datum_t tmp = {NULL, 0}; int params_start, params_end, params_len; struct pbkdf2_params kdf_params; struct pbe_enc_params enc_params; schema_id schema; /* Check the encryption schema OID */ len = sizeof(enc_oid); result = asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm", enc_oid, &len); if (result != ASN1_SUCCESS) { gnutls_assert(); goto error; } if ((result = _gnutls_check_pkcs_cipher_schema(enc_oid)) < 0) { gnutls_assert(); goto error; } schema = result; /* Get the DER encoding of the parameters. */ result = asn1_der_decoding_startEnd(pkcs8_asn, raw_key->data, raw_key->size, "encryptionAlgorithm.parameters", ¶ms_start, ¶ms_end); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto error; } params_len = params_end - params_start + 1; result = _gnutls_read_pkcs_schema_params(&schema, password, &raw_key->data[params_start], params_len, &kdf_params, &enc_params); if (result < 0) { gnutls_assert(); goto error; } /* Parameters have been decoded. Now * decrypt the EncryptedData. */ result = _gnutls_pkcs_raw_decrypt_data(schema, pkcs8_asn, "encryptedData", password, &kdf_params, &enc_params, &tmp); if (result < 0) { gnutls_assert(); result = GNUTLS_E_DECRYPTION_FAILED; goto error; } result = decode_private_key_info(&tmp, pkey); _gnutls_free_key_datum(&tmp); CHECK_ERR_FOR_ENCRYPTED(result); if (result < 0) { gnutls_assert(); goto error; } return 0; error: return result; }
/** * gnutls_pkcs7_get_crt_raw: * @pkcs7: should contain a gnutls_pkcs7_t structure * @indx: contains the index of the certificate to extract * @certificate: the contents of the certificate will be copied * there (may be null) * @certificate_size: should hold the size of the certificate * * This function will return a certificate of the PKCS7 or RFC2630 * certificate set. * * After the last certificate 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. If the provided buffer is not long enough, * then @certificate_size is updated and * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned. **/ int gnutls_pkcs7_get_crt_raw (gnutls_pkcs7_t pkcs7, int indx, void *certificate, size_t * certificate_size) { ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int result, len; char root2[ASN1_MAX_NAME_SIZE]; char oid[MAX_OID_SIZE]; gnutls_datum_t tmp = { NULL, 0 }; if (certificate_size == NULL || pkcs7 == 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), "certificates.?%u", indx + 1); len = sizeof (oid) - 1; result = asn1_read_value (c2, root2, oid, &len); if (result == ASN1_VALUE_NOT_FOUND) { result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; goto cleanup; } if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* if 'Certificate' is the choice found: */ if (strcmp (oid, "certificate") == 0) { int start, end; 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 > *certificate_size) { *certificate_size = end; result = GNUTLS_E_SHORT_MEMORY_BUFFER; goto cleanup; } if (certificate) memcpy (certificate, &tmp.data[start], end); *certificate_size = end; result = 0; } else { result = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } cleanup: _gnutls_free_datum (&tmp); if (c2) asn1_delete_structure (&c2); return result; }