in kmsp11/session.cc [40:127]
absl::StatusOr<KeyGenerationParams> ExtractKeyGenerationParams(
absl::Span<const CK_ATTRIBUTE> prv_template, bool allow_software_keys) {
std::optional<std::string> label;
std::optional<kms_v1::CryptoKeyVersion::CryptoKeyVersionAlgorithm> algorithm;
std::optional<kms_v1::ProtectionLevel> protection_level;
for (const CK_ATTRIBUTE& attr : prv_template) {
switch (attr.type) {
case CKA_LABEL:
label =
std::string(reinterpret_cast<char*>(attr.pValue), attr.ulValueLen);
static std::regex* label_regexp = new std::regex("[a-zA-Z0-9_-]{1,63}");
if (!std::regex_match(*label, *label_regexp)) {
return NewInvalidArgumentError(
"CKA_LABEL must be a valid Cloud KMS CryptoKey ID",
CKR_ATTRIBUTE_VALUE_INVALID, SOURCE_LOCATION);
}
break;
case CKA_KMS_ALGORITHM:
if (attr.ulValueLen != sizeof(CK_ULONG)) {
return NewInvalidArgumentError(
absl::StrFormat("CKA_KMS_ALGORITHM value should be CK_ULONG "
"(size=%d, got=%d)",
sizeof(CK_ULONG), attr.ulValueLen),
CKR_ATTRIBUTE_VALUE_INVALID, SOURCE_LOCATION);
}
algorithm = kms_v1::CryptoKeyVersion::CryptoKeyVersionAlgorithm(
*static_cast<CK_ULONG*>(attr.pValue));
break;
case CKA_KMS_PROTECTION_LEVEL:
if (attr.ulValueLen != sizeof(CK_ULONG)) {
return NewInvalidArgumentError(
absl::StrFormat(
"CKA_KMS_PROTECTION_LEVEL value should be CK_ULONG "
"(size=%d, got=%d)",
sizeof(CK_ULONG), attr.ulValueLen),
CKR_ATTRIBUTE_VALUE_INVALID, SOURCE_LOCATION);
}
protection_level =
kms_v1::ProtectionLevel(*static_cast<CK_ULONG*>(attr.pValue));
if (protection_level != kms_v1::SOFTWARE &&
protection_level != kms_v1::HSM) {
return NewInvalidArgumentError(
absl::StrFormat("CKA_KMS_PROTECTION_LEVEL value should be "
"1(SOFTWARE) or 2(HSM) "
", got=%d",
attr.ulValueLen),
CKR_ATTRIBUTE_VALUE_INVALID, SOURCE_LOCATION);
}
if (protection_level == kms_v1::SOFTWARE && !allow_software_keys) {
return NewInvalidArgumentError(
"CKA_KMS_PROTECTION_LEVEL cannot be SOFTWARE because only keys "
"with protection level = HSM are "
"allowed. If you want to be able to create software keys, use "
"allow_software_keys in the "
"configuration.",
CKR_ATTRIBUTE_VALUE_INVALID, SOURCE_LOCATION);
}
break;
default:
return NewInvalidArgumentError(
absl::StrFormat(
"this token does not permit specifying attribute type %#x",
attr.type),
CKR_TEMPLATE_INCONSISTENT, SOURCE_LOCATION);
}
}
if (!label.has_value()) {
return NewInvalidArgumentError("CKA_LABEL must be specified for the key",
CKR_TEMPLATE_INCOMPLETE, SOURCE_LOCATION);
}
if (!algorithm.has_value()) {
return NewInvalidArgumentError(
"CKA_KMS_ALGORITHM must be specified for the key",
CKR_TEMPLATE_INCOMPLETE, SOURCE_LOCATION);
}
absl::StatusOr<AlgorithmDetails> algorithm_details = GetDetails(*algorithm);
if (!algorithm_details.ok()) {
return NewInvalidArgumentError(algorithm_details.status().message(),
CKR_ATTRIBUTE_VALUE_INVALID,
SOURCE_LOCATION);
}
return KeyGenerationParams{*label, *algorithm_details, protection_level};
}