Esempio n. 1
0
static int
ShroudedKeyBag_parser(hx509_context context,
		      struct hx509_collector *c,
		      const void *data, size_t length,
		      const PKCS12_Attributes *attrs)
{
    PKCS8EncryptedPrivateKeyInfo pk;
    heim_octet_string content;
    int ret;

    memset(&pk, 0, sizeof(pk));

    ret = decode_PKCS8EncryptedPrivateKeyInfo(data, length, &pk, NULL);
    if (ret)
	return ret;

    ret = _hx509_pbe_decrypt(context,
			     _hx509_collector_get_lock(c),
			     &pk.encryptionAlgorithm,
			     &pk.encryptedData,
			     &content);
    free_PKCS8EncryptedPrivateKeyInfo(&pk);
    if (ret)
	return ret;

    ret = keyBag_parser(context, c, content.data, content.length, attrs);
    der_free_octet_string(&content);
    return ret;
}
Esempio n. 2
0
static int
encryptedData_parser(hx509_context context,
		     struct hx509_collector *c,
		     const void *data, size_t length,
		     const PKCS12_Attributes *attrs)
{
    heim_octet_string content;
    heim_oid contentType;
    int ret;

    memset(&contentType, 0, sizeof(contentType));

    ret = hx509_cms_decrypt_encrypted(context,
				      _hx509_collector_get_lock(c),
				      data, length,
				      &contentType,
				      &content);
    if (ret)
	return ret;

    if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0)
	ret = parse_safe_content(context, c, content.data, content.length);

    der_free_octet_string(&content);
    der_free_oid(&contentType);
    return ret;
}
Esempio n. 3
0
static int
envelopedData_parser(hx509_context context,
		     struct hx509_collector *c,
		     const void *data, size_t length,
		     const PKCS12_Attributes *attrs)
{
    heim_octet_string content;
    heim_oid contentType;
    hx509_lock lock;
    int ret;

    memset(&contentType, 0, sizeof(contentType));

    lock = _hx509_collector_get_lock(c);

    ret = hx509_cms_unenvelope(context,
			       _hx509_lock_unlock_certs(lock),
			       0,
			       data, length,
			       NULL,
			       0,
			       &contentType,
			       &content);
    if (ret) {
	hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
			       "PKCS12 failed to unenvelope");
	return ret;
    }

    if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0)
	ret = parse_safe_content(context, c, content.data, content.length);

    der_free_octet_string(&content);
    der_free_oid(&contentType);

    return ret;
}
Esempio n. 4
0
static int
parse_rsa_private_key(hx509_context context, const char *fn,
		      struct hx509_collector *c,
		      const hx509_pem_header *headers,
		      const void *data, size_t len)
{
    int ret = 0;
    const char *enc;

    enc = hx509_pem_find_header(headers, "Proc-Type");
    if (enc) {
	const char *dek;
	char *type, *iv;
	ssize_t ssize, size;
	void *ivdata;
	const EVP_CIPHER *cipher;
	const struct _hx509_password *pw;
	hx509_lock lock;
	int i, decrypted = 0;

	lock = _hx509_collector_get_lock(c);
	if (lock == NULL) {
	    hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
				   "Failed to get password for "
				   "password protected file %s", fn);
	    return HX509_ALG_NOT_SUPP;
	}

	if (strcmp(enc, "4,ENCRYPTED") != 0) {
	    hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
				   "RSA key encrypted in unknown method %s "
				   "in file",
				   enc, fn);
	    hx509_clear_error_string(context);
	    return HX509_PARSING_KEY_FAILED;
	}

	dek = hx509_pem_find_header(headers, "DEK-Info");
	if (dek == NULL) {
	    hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
				   "Encrypted RSA missing DEK-Info");
	    return HX509_PARSING_KEY_FAILED;
	}

	type = strdup(dek);
	if (type == NULL) {
	    hx509_clear_error_string(context);
	    return ENOMEM;
	}

	iv = strchr(type, ',');
	if (iv == NULL) {
	    free(type);
	    hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
				   "IV missing");
	    return HX509_PARSING_KEY_FAILED;
	}

	*iv++ = '\0';

	size = strlen(iv);
	ivdata = malloc(size);
	if (ivdata == NULL) {
	    hx509_clear_error_string(context);
	    free(type);
	    return ENOMEM;
	}

	cipher = EVP_get_cipherbyname(type);
	if (cipher == NULL) {
	    free(ivdata);
	    hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
				   "RSA key encrypted with "
				   "unsupported cipher: %s",
				   type);
	    free(type);
	    return HX509_ALG_NOT_SUPP;
	}

#define PKCS5_SALT_LEN 8

	ssize = hex_decode(iv, ivdata, size);
	free(type);
	type = NULL;
	iv = NULL;

	if (ssize < 0 || ssize < PKCS5_SALT_LEN || ssize < EVP_CIPHER_iv_length(cipher)) {
	    free(ivdata);
	    hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
				   "Salt have wrong length in RSA key file");
	    return HX509_PARSING_KEY_FAILED;
	}
	
	pw = _hx509_lock_get_passwords(lock);
	if (pw != NULL) {
	    const void *password;
	    size_t passwordlen;

	    for (i = 0; i < pw->len; i++) {
		password = pw->val[i];
		passwordlen = strlen(password);
		
		ret = try_decrypt(context, c, hx509_signature_rsa(),
				  cipher, ivdata, password, passwordlen,
				  data, len);
		if (ret == 0) {
		    decrypted = 1;
		    break;
		}
	    }
	}
	if (!decrypted) {
	    hx509_prompt prompt;
	    char password[128];

	    memset(&prompt, 0, sizeof(prompt));

	    prompt.prompt = "Password for keyfile: ";
	    prompt.type = HX509_PROMPT_TYPE_PASSWORD;
	    prompt.reply.data = password;
	    prompt.reply.length = sizeof(password);

	    ret = hx509_lock_prompt(lock, &prompt);
	    if (ret == 0)
		ret = try_decrypt(context, c, hx509_signature_rsa(),
				  cipher, ivdata, password, strlen(password),
				  data, len);
	    /* XXX add password to lock password collection ? */
	    memset(password, 0, sizeof(password));
	}
	free(ivdata);

    } else {
	heim_octet_string keydata;

	keydata.data = rk_UNCONST(data);
	keydata.length = len;

	ret = _hx509_collector_private_key_add(context,
					       c,
					       hx509_signature_rsa(),
					       NULL,
					       &keydata,
					       NULL);
    }

    return ret;
}