Bug 1282627 - Merge can be confused with a modified trust flags set.
authorRobert Relyea <rrelyea@redhat.com>
Wed, 26 Oct 2016 11:12:57 -0700
changeset 12768 24232beee1f204c690b2be50845f779dc751ee98
parent 12767 87927a9d502ed68eb3360ed11fd53b19d23dd2af
child 12769 7701b1b052aa31ddf3159d489ebba777094e055c
push id1710
push userrrelyea@redhat.com
push dateWed, 26 Oct 2016 18:13:02 +0000
bugs1282627
Bug 1282627 - Merge can be confused with a modified trust flags set. r=franziskus
lib/pk11wrap/pk11merge.c
tests/merge/merge.sh
--- a/lib/pk11wrap/pk11merge.c
+++ b/lib/pk11wrap/pk11merge.c
@@ -56,30 +56,55 @@ pk11_setAttributes(PK11SlotInfo *slot, C
  * if target object is not given, create it.
  */
 static SECStatus
 pk11_copyAttributes(PLArenaPool *arena,
 	PK11SlotInfo *targetSlot, CK_OBJECT_HANDLE targetID,
 	PK11SlotInfo *sourceSlot, CK_OBJECT_HANDLE sourceID,
 	CK_ATTRIBUTE *copyTemplate, CK_ULONG copyTemplateCount)
 {
-    SECStatus rv = PK11_GetAttributes(arena, sourceSlot, sourceID, 
+    SECStatus rv;
+    CK_ATTRIBUTE *newTemplate = NULL;
+    CK_RV crv;
+
+    crv  = PK11_GetAttributes(arena, sourceSlot, sourceID,
 				copyTemplate, copyTemplateCount);
-    if (rv != SECSuccess) {
-	return rv;
+    /* if we have missing attributes, just skip them and create the object */
+    if (crv == CKR_ATTRIBUTE_TYPE_INVALID) {
+	int i,j;
+	newTemplate = PORT_NewArray(CK_ATTRIBUTE, copyTemplateCount);
+	/* remove the unknown attributes. If we don't have enough attributes
+	 * PK11_CreateNewObject() will fail */
+	for (i=0,j=0; i < copyTemplateCount; i++) {
+	    if (copyTemplate[i].ulValueLen != -1) {
+		newTemplate[j] = copyTemplate[i];
+		j++;
+	    }
+	}
+	copyTemplate = newTemplate;
+	copyTemplateCount = j;
+    	crv  = PK11_GetAttributes(arena, sourceSlot, sourceID,
+				copyTemplate, copyTemplateCount);
+    }
+    if (crv != CKR_OK) {
+ 	PORT_SetError( PK11_MapError(crv) );
+	return SECFailure;
     }
     if (targetID == CK_INVALID_HANDLE) {
 	/* we need to create the object */
-	rv = PK11_CreateNewObject(targetSlot, CK_INVALID_SESSION, 
+	rv = PK11_CreateNewObject(targetSlot, CK_INVALID_SESSION,
 		copyTemplate, copyTemplateCount, PR_TRUE, &targetID);
     } else {
 	/* update the existing object with the new attributes */
-	rv = pk11_setAttributes(targetSlot, targetID, 
+	rv = pk11_setAttributes(targetSlot, targetID,
 			copyTemplate, copyTemplateCount);
     }
+    if (newTemplate) {
+	free(newTemplate);
+    }
     return rv;
 }
 
 /*
  * look for a matching object across tokens.
  */
 static SECStatus
 pk11_matchAcrossTokens(PLArenaPool *arena, PK11SlotInfo *targetSlot,
--- a/tests/merge/merge.sh
+++ b/tests/merge/merge.sh
@@ -99,17 +99,19 @@ merge_init()
   if [ "${TEST_MODE}" = "UPGRADE_DB" ]; then
 	save=${NSS_DEFAULT_DB_TYPE}
 	NSS_DEFAULT_DB_TYPE= ; export NSS_DEFAULT_DB_TYPE
   fi
 
   certutil -N -d ${CONFLICT1DIR} -f ${R_PWFILE}
   certutil -N -d ${CONFLICT2DIR} -f ${R_PWFILE}
   certutil -A -n Alice -t ,, -i ${R_CADIR}/TestUser41.cert -d ${CONFLICT1DIR}
-  certutil -A -n "Alice #1" -t ,, -i ${R_CADIR}/TestUser42.cert -d ${CONFLICT1DIR}
+  # modify CONFLICTDIR potentially corrupting the database
+  certutil -A -n "Alice #1" -t C,, -i ${R_CADIR}/TestUser42.cert -d ${CONFLICT1DIR} -f ${R_PWFILE}
+  certutil -M -n "Alice #1" -t ,, -d ${CONFLICT1DIR} -f ${R_PWFILE}
   certutil -A -n "Alice #99" -t ,, -i ${R_CADIR}/TestUser43.cert -d ${CONFLICT1DIR}
   certutil -A -n Alice -t ,, -i ${R_CADIR}/TestUser44.cert -d ${CONFLICT2DIR}
   certutil -A -n "Alice #1" -t ,, -i ${R_CADIR}/TestUser45.cert -d ${CONFLICT2DIR}
   certutil -A -n "Alice #99" -t ,, -i ${R_CADIR}/TestUser46.cert -d ${CONFLICT2DIR}
   if [ "${TEST_MODE}" = "UPGRADE_DB" ]; then
 	NSS_DEFAULT_DB_TYPE=${save}; export NSS_DEFAULT_DB_TYPE
   fi
 
@@ -263,10 +265,13 @@ merge_cleanup()
   cd ${QADIR}
   . common/cleanup.sh
 }
 
 ################## main #################################################
 
 merge_init
 merge_main
+echo "TEST_MODE=${TEST_MODE}"
+echo "NSS_DEFAULT_DB_TYPE=${NSS_DEFAULT_DB_TYPE}"
 merge_cleanup
 
+