Esempio n. 1
0
/**
 * 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.
 *
 * This function does not output a fully RFC4514 compliant string, if
 * that is required see gnutls_x509_rdn_get2().
 *
 * 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_strict_der_decode(&dn, idn->data, idn->size, NULL);
	if (result != ASN1_SUCCESS) {
		/* couldn't decode DER */
		gnutls_assert();
		asn1_delete_structure(&dn);
		return _gnutls_asn2err(result);
	}

	result = _gnutls_x509_parse_dn(dn, "rdnSequence", buf, buf_size, GNUTLS_X509_DN_FLAG_COMPAT);

	asn1_delete_structure(&dn);
	return result;

}
Esempio n. 2
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",
				       &params_start, &params_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;
}
Esempio n. 3
0
static int
decode_private_key_info(const gnutls_datum_t * der,
			gnutls_x509_privkey_t pkey)
{
	int result, len;
	char oid[MAX_OID_SIZE];
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
	gnutls_datum_t sder;
	int ret;

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-PrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result = _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Check the private key algorithm OID
	 */
	len = sizeof(oid);
	result =
	    asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.algorithm",
			    oid, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	pkey->params.algo = gnutls_oid_to_pk(oid);
	if (pkey->params.algo == GNUTLS_PK_UNKNOWN) {
		gnutls_assert();
		_gnutls_debug_log
		    ("PKCS #8 private key OID '%s' is unsupported.\n",
		     oid);
		result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
		goto error;
	}

	/* Get the DER encoding of the actual private key.
	 */

	switch(pkey->params.algo) {
		case GNUTLS_PK_RSA:
			result = _decode_pkcs8_rsa_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_RSA_PSS:
			result = _decode_pkcs8_rsa_pss_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_DSA:
			result = _decode_pkcs8_dsa_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_ECDSA:
			result = _decode_pkcs8_ecc_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_EDDSA_ED25519:
			result = _decode_pkcs8_eddsa_key(pkcs8_asn, pkey, oid);
			break;
		case GNUTLS_PK_GOST_01:
		case GNUTLS_PK_GOST_12_256:
		case GNUTLS_PK_GOST_12_512:
			result = _decode_pkcs8_gost_key(pkcs8_asn,
							pkey, pkey->params.algo);
			break;
		default:
			result = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
			goto error;
	}

	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	/* check for provable parameters attribute */
	ret = _x509_parse_attribute(pkcs8_asn, "attributes", OID_ATTR_PROV_SEED, 0, 1, &sder);
	if (ret >= 0) { /* ignore it when not being present */
		ret = _x509_decode_provable_seed(pkey, &sder);
		gnutls_free(sder.data);
		if (ret < 0) {
			gnutls_assert();
		}
	}

	result = 0;

error:
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;

}
Esempio n. 4
0
/* Converts a GOST key to
 * an internal structure (gnutls_private_key)
 */
static int
_privkey_decode_gost_key(const gnutls_datum_t * raw_key,
			 gnutls_x509_privkey_t pkey)
{
	int ret;
	int ecc_size = gnutls_ecc_curve_get_size(pkey->params.curve);

	/* Just to be sure here */
	if (ecc_size <= 0) {
		gnutls_assert();
		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
		goto error;
	}

	/* Private key form described in R 50.1.112-2016.
	 * Private key can come up as masked value concatenated with several masks.
	 * each part is of ecc_size bytes. Key will be unmasked in pk_fixup */
	if (raw_key->size % ecc_size == 0) {
		ret = _gnutls_mpi_init_scan_le(&pkey->params.params[GOST_K],
				raw_key->data, raw_key->size);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (raw_key->data[0] == ASN1_TAG_INTEGER) {
		ASN1_TYPE pkey_asn;

		/* Very old format: INTEGER packed in OCTET STRING */
		if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
					       "GNUTLS.GOSTPrivateKeyOld",
					       &pkey_asn)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		ret = _asn1_strict_der_decode(&pkey_asn,
				raw_key->data, raw_key->size,
				NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}

		ret = _gnutls_x509_read_key_int(pkey_asn, "",
						&pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}
		asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	} else if (raw_key->data[0] == ASN1_TAG_OCTET_STRING) {
		ASN1_TYPE pkey_asn;

		/* format: OCTET STRING packed in OCTET STRING */
		if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
					       "GNUTLS.GOSTPrivateKey",
					       &pkey_asn)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		ret = _asn1_strict_der_decode(&pkey_asn,
				raw_key->data, raw_key->size,
				NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}

		ret = _gnutls_x509_read_key_int_le(pkey_asn, "",
						   &pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}
		asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	} else {
		gnutls_assert();
		ret = GNUTLS_E_PARSING_ERROR;
		goto error;
	}

	pkey->params.params_nr++;

	return 0;

      error:
	return ret;

}
Esempio n. 5
0
static int
decode_complex_string(const struct oid_to_string *oentry, void *value,
		      int value_size, gnutls_datum_t * out)
{
	char str[MAX_STRING_LEN], tmpname[128];
	int len = -1, result;
	ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
	char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
	unsigned int etype;
	gnutls_datum_t td = {NULL, 0};

	if (oentry->asn_desc == NULL) {
		gnutls_assert();
		return GNUTLS_E_INTERNAL_ERROR;
	}

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc,
				 &tmpasn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	if ((result =
	     _asn1_strict_der_decode(&tmpasn, value, value_size,
			       asn1_err)) != ASN1_SUCCESS) {
		gnutls_assert();
		_gnutls_debug_log("_asn1_strict_der_decode: %s\n", asn1_err);
		asn1_delete_structure(&tmpasn);
		return _gnutls_asn2err(result);
	}

	/* Read the type of choice.
	 */
	len = sizeof(str) - 1;
	if ((result = asn1_read_value(tmpasn, "", str, &len)) != ASN1_SUCCESS) {	/* CHOICE */
		gnutls_assert();
		asn1_delete_structure(&tmpasn);
		return _gnutls_asn2err(result);
	}

	str[len] = 0;

	/* We set the etype on the strings that may need
	 * some conversion to UTF-8. The INVALID flag indicates
	 * no conversion needed */
	if (strcmp(str, "teletexString") == 0)
		etype = ASN1_ETYPE_TELETEX_STRING;
	else if (strcmp(str, "bmpString") == 0)
		etype = ASN1_ETYPE_BMP_STRING;
	else if (strcmp(str, "universalString") == 0)
		etype = ASN1_ETYPE_UNIVERSAL_STRING;
	else
		etype = ASN1_ETYPE_INVALID;

	_gnutls_str_cpy(tmpname, sizeof(tmpname), str);

	result = _gnutls_x509_read_value(tmpasn, tmpname, &td);
	asn1_delete_structure(&tmpasn);
	if (result < 0)
		return gnutls_assert_val(result);

	if (etype != ASN1_ETYPE_INVALID) {
		result = make_printable_string(etype, &td, out);

		_gnutls_free_datum(&td);

		if (result < 0)
			return gnutls_assert_val(result);
	} else {
		out->data = td.data;
		out->size = td.size;
		/* _gnutls_x509_read_value always null terminates */
	}

	/* Refuse to deal with strings containing NULs. */
	if (strlen((void *) out->data) != (size_t) out->size) {
		_gnutls_free_datum(out);
		return gnutls_assert_val(GNUTLS_E_ASN1_EMBEDDED_NULL_IN_STRING);
	}

	return 0;
}
Esempio n. 6
0
int _gnutls_read_pbkdf1_params(const uint8_t * data, int data_size,
		       struct pbkdf2_params *kdf_params,
		       struct pbe_enc_params *enc_params)
{
	ASN1_TYPE pasn = ASN1_TYPE_EMPTY;
	int len;
	int ret, result;

	memset(kdf_params, 0, sizeof(*kdf_params));
	memset(enc_params, 0, sizeof(*enc_params));

	if ((result =
		     asn1_create_element(_gnutls_get_pkix(),
					 "PKIX1.pkcs-5-PBE-params",
					 &pasn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	/* Decode the parameters.
	 */
	result =
	    _asn1_strict_der_decode(&pasn, data, data_size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto error;
	}

	ret =
	    _gnutls_x509_read_uint(pasn, "iterationCount",
			   &kdf_params->iter_count);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (kdf_params->iter_count >= MAX_ITER_COUNT || kdf_params->iter_count == 0) {
		ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
		goto error;
	}

	len = sizeof(kdf_params->salt);
	result =
	    asn1_read_value(pasn, "salt",
		    kdf_params->salt, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto error;
	}

	if (len != 8) {
		gnutls_assert();
		ret = GNUTLS_E_ILLEGAL_PARAMETER;
		goto error;
	}

	enc_params->cipher = GNUTLS_CIPHER_DES_CBC;

	ret = 0;
 error:
	asn1_delete_structure2(&pasn, ASN1_DELETE_FLAG_ZEROIZE);
	return ret;

}