Skip to content

Commit 0f972d8

Browse files
authored
Merge pull request #728 from antoinelochet/fix_issue_707
Allow OBJECT_OP_UNWRAP to modify attributes
2 parents 4475560 + 26ec19a commit 0f972d8

File tree

3 files changed

+118
-2
lines changed

3 files changed

+118
-2
lines changed

src/lib/P11Attributes.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,13 +411,13 @@ CK_RV P11Attribute::update(Token* token, bool isPrivate, CK_VOID_PTR pValue, CK_
411411
// given non-Cryptoki attribute is read-only is obviously outside the scope of Cryptoki.
412412

413413
// Attributes cannot be changed if CKA_MODIFIABLE is set to false
414-
if (!isModifiable() && op != OBJECT_OP_GENERATE && op != OBJECT_OP_CREATE) {
414+
if (!isModifiable() && op != OBJECT_OP_GENERATE && op != OBJECT_OP_CREATE && op != OBJECT_OP_UNWRAP) {
415415
ERROR_MSG("An object is with CKA_MODIFIABLE set to false is not modifiable");
416416
return CKR_ATTRIBUTE_READ_ONLY;
417417
}
418418

419419
// Attributes cannot be modified if CKA_TRUSTED is true on a certificate object.
420-
if (isTrusted() && op != OBJECT_OP_GENERATE && op != OBJECT_OP_CREATE) {
420+
if (isTrusted() && op != OBJECT_OP_GENERATE && op != OBJECT_OP_CREATE && op != OBJECT_OP_UNWRAP) {
421421
if (osobject->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) == CKO_CERTIFICATE)
422422
{
423423
ERROR_MSG("A trusted certificate cannot be modified");

src/lib/test/SymmetricAlgorithmTests.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,119 @@ void SymmetricAlgorithmTests::aesWrapUnwrapGeneric(CK_MECHANISM_TYPE mechanismTy
11861186
CPPUNIT_ASSERT(rv == CKR_OK);
11871187
}
11881188

1189+
void SymmetricAlgorithmTests::aesWrapUnwrapNonModifiableGeneric(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
1190+
{
1191+
CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
1192+
CK_BBOOL bFalse = CK_FALSE;
1193+
CK_BBOOL bTrue = CK_TRUE;
1194+
CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
1195+
CK_KEY_TYPE genKeyType = CKK_GENERIC_SECRET;
1196+
CK_BYTE keyPtr[128];
1197+
CK_ULONG keyLen =
1198+
mechanismType == CKM_AES_KEY_WRAP_PAD ? 125UL : 128UL;
1199+
1200+
CK_RV rv;
1201+
CK_BYTE ivPtr[16];
1202+
if( mechanismType == CKM_AES_CBC_PAD ) {
1203+
rv = CRYPTOKI_F_PTR( C_GenerateRandom(hSession, ivPtr, sizeof ivPtr) );
1204+
CPPUNIT_ASSERT(rv == CKR_OK);
1205+
mechanism.pParameter = ivPtr;
1206+
mechanism.ulParameterLen = sizeof ivPtr;
1207+
}
1208+
1209+
CK_ATTRIBUTE attribs[] = {
1210+
{ CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) },
1211+
{ CKA_CLASS, &secretClass, sizeof(secretClass) },
1212+
{ CKA_KEY_TYPE, &genKeyType, sizeof(genKeyType) },
1213+
{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
1214+
{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
1215+
{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, // Wrapping is allowed even on sensitive objects
1216+
{ CKA_VALUE, keyPtr, keyLen }
1217+
};
1218+
CK_OBJECT_HANDLE hSecret;
1219+
1220+
rv = CRYPTOKI_F_PTR( C_GenerateRandom(hSession, keyPtr, keyLen) );
1221+
CPPUNIT_ASSERT(rv == CKR_OK);
1222+
1223+
hSecret = CK_INVALID_HANDLE;
1224+
rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hSecret) );
1225+
CPPUNIT_ASSERT(rv == CKR_OK);
1226+
CPPUNIT_ASSERT(hSecret != CK_INVALID_HANDLE);
1227+
1228+
CK_BYTE_PTR wrappedPtr = NULL_PTR;
1229+
CK_ULONG wrappedLen = 0UL;
1230+
CK_ULONG zero = 0UL;
1231+
CK_ULONG rndKeyLen = keyLen;
1232+
if (mechanismType == CKM_AES_KEY_WRAP_PAD)
1233+
rndKeyLen = (keyLen + 7) & ~7;
1234+
rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
1235+
CPPUNIT_ASSERT(rv == CKR_KEY_UNEXTRACTABLE);
1236+
rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hSecret) );
1237+
CPPUNIT_ASSERT(rv == CKR_OK);
1238+
1239+
attribs[0].pValue = &bTrue;
1240+
1241+
hSecret = CK_INVALID_HANDLE;
1242+
rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hSecret) );
1243+
CPPUNIT_ASSERT(rv == CKR_OK);
1244+
CPPUNIT_ASSERT(hSecret != CK_INVALID_HANDLE);
1245+
1246+
// Estimate wrapped length
1247+
rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
1248+
CPPUNIT_ASSERT(rv == CKR_OK);
1249+
1250+
auto wrapOverhead = [mechanismType]() {
1251+
return (mechanismType == CKM_AES_KEY_WRAP || mechanismType == CKM_AES_KEY_WRAP_PAD) ? 8 : 16;
1252+
};
1253+
CPPUNIT_ASSERT(wrappedLen == rndKeyLen + wrapOverhead() );
1254+
1255+
wrappedPtr = (CK_BYTE_PTR) malloc(wrappedLen);
1256+
CPPUNIT_ASSERT(wrappedPtr != NULL_PTR);
1257+
rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
1258+
CPPUNIT_ASSERT(rv == CKR_OK);
1259+
CPPUNIT_ASSERT(wrappedLen == rndKeyLen + wrapOverhead() );
1260+
1261+
// This should always fail because wrapped data have to be longer than 0 bytes
1262+
zero = 0;
1263+
rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &zero) );
1264+
CPPUNIT_ASSERT(rv == CKR_BUFFER_TOO_SMALL);
1265+
1266+
CK_ATTRIBUTE nattribs[] = {
1267+
{ CKA_CLASS, &secretClass, sizeof(secretClass) },
1268+
{ CKA_KEY_TYPE, &genKeyType, sizeof(genKeyType) },
1269+
{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
1270+
{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
1271+
{ CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
1272+
{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
1273+
{ CKA_MODIFIABLE, &bFalse, sizeof(bFalse) },
1274+
{ CKA_SIGN, &bFalse,sizeof(bFalse) },
1275+
{ CKA_VERIFY, &bTrue, sizeof(bTrue) }
1276+
};
1277+
CK_OBJECT_HANDLE hNew;
1278+
1279+
hNew = CK_INVALID_HANDLE;
1280+
rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nattribs, sizeof(nattribs)/sizeof(CK_ATTRIBUTE), &hNew) );
1281+
CPPUNIT_ASSERT(rv == CKR_OK);
1282+
CPPUNIT_ASSERT(hNew != CK_INVALID_HANDLE);
1283+
1284+
CK_ATTRIBUTE modifiableAttribs[] = {
1285+
{ CKA_MODIFIABLE, &bFalse, sizeof(bFalse) }
1286+
};
1287+
1288+
rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hNew, modifiableAttribs, sizeof(modifiableAttribs)/sizeof(CK_ATTRIBUTE)) );
1289+
CPPUNIT_ASSERT(rv == CKR_OK);
1290+
1291+
CPPUNIT_ASSERT(modifiableAttribs[0].ulValueLen == sizeof(bFalse));
1292+
CPPUNIT_ASSERT(*(CK_BBOOL*)modifiableAttribs[0].pValue == bFalse);
1293+
1294+
free(wrappedPtr);
1295+
wrappedPtr = NULL_PTR;
1296+
rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hSecret) );
1297+
CPPUNIT_ASSERT(rv == CKR_OK);
1298+
rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hNew) );
1299+
CPPUNIT_ASSERT(rv == CKR_OK);
1300+
}
1301+
11891302
inline void SymmetricAlgorithmTests::aesWrapUnwrapRsa(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
11901303
{
11911304
wrapUnwrapRsa(mechanismType, hSession, hKey);
@@ -1643,6 +1756,8 @@ void SymmetricAlgorithmTests::testAesWrapUnwrap()
16431756

16441757
aesWrapUnwrapGeneric(CKM_AES_KEY_WRAP, hSession, hKey);
16451758
aesWrapUnwrapGeneric(CKM_AES_CBC_PAD, hSession, hKey);
1759+
aesWrapUnwrapNonModifiableGeneric(CKM_AES_KEY_WRAP, hSession, hKey);
1760+
aesWrapUnwrapNonModifiableGeneric(CKM_AES_CBC_PAD, hSession, hKey);
16461761
aesWrapUnwrapRsa(CKM_AES_KEY_WRAP, hSession, hKey);
16471762
aesWrapUnwrapRsa(CKM_AES_CBC_PAD, hSession, hKey);
16481763

src/lib/test/SymmetricAlgorithmTests.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class SymmetricAlgorithmTests : public TestsBase
8888
size_t messageSize,
8989
bool isSizeOK=true);
9090
void aesWrapUnwrapGeneric(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey);
91+
void aesWrapUnwrapNonModifiableGeneric(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey);
9192
void aesWrapUnwrapRsa(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey);
9293
void desWrapUnwrapRsa(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey);
9394
CK_RV generateRsaPrivateKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey);

0 commit comments

Comments
 (0)