The following pseudo-code fragments provide examples of how to protect and unprotect a message using MQeMAttribute and MQeMTrustAttribute
/*SIMPLE PROTECT FRAGMENT */ MQeMsgHndl msgObj; MQeMAttributeHndl attr = null; MQeInt64 confirmId; MQERETURN rc; MQeExceptBlock exceptBlock; MQe3DESCryptorHndl tdes; MQeMAttributeHndl attr; MQeKeyHndl localkey; MQeMsgHndl msgObj; /* create the cryptor */ rc = mqe_uniqueValue(&exceptBlock, &confirmId); rc = mqe3DESCryptor_new(&exceptBlock, &tdes); /* create an attribute using the cryptor */ rc = mqeMAttribute_new(&exceptBlock,&attr, NULL,tdes,NULL); /* create a local key */ rc = mqeKey_new(&exceptBlock,&localkey); /* give it the key seed */ rc = mqeKey_setLocalKey(localkey, new(&exceptBlock, MQeString("my secret key")); /* set the key in the attribute */ rc = mqeMAttribute_setKey(attr, &exceptBlock, localkey ); /* create the message */ rc = mqeMsg_new(&exceptBlock, &msObj); rc = mqeFields_putAscii(msgObj, &exceptBlock, MQeString("MsgData"), MQeString("0123456789abcdef...")); /* put the message using the attribute */ rc = mqeQueueManager_putMessage(newQM, &exceptBlock, targetQMgrName, targetQName, msgObj, attr, confirmId ); /*SIMPLE UNPROTECT FRAGMENT */ MQeMsgHndl msgObj2; MQeMAttributeHndl attr2; MQeInt64 confirmId2; MQeKeyHndl localkey; MQERETURN rc; MQeExceptBlock exceptBlock; rc = mqe_uniqueValue(&exceptBlock, &confirmId2); /* create the attribute - we do not have to specify the cryptor, */ /* the attribute can get this from the message itself */ rc = mqeMAttribute_new(&exceptBlock, &attr2, NULL, NULL, NULL); /* create a local key */ rc = mqeKey_new(&exceptBlock, &localkey); /* give it the key seed */ rc = mqeKey_setLocalKey(localkey, &exceptBlock,MQeString("my secret key")); /* set the key in the attribute */ rc = mqeMAttribute_setKey(attr2, &exceptBlock, localkey ); /* get the message using the attribute */ rc = mqeQueueManager_getMessage(newQM, &exceptBlock, &msgObj2, targetQMgrName, targetQName, NULL, attr2, confirmId2 );
/*SIMPLE PROTECT FRAGMENT */ MQeMsgHndl msgObj; MQeMTrustAttributeHndl attr; MQeMARSCryptorHndl mars; MQePrivateRegistryHndl sendreg; MQePublicRegistryHndl pr; MQeMsgObjectHndl msgObj; MQeInt64 confirmId; MQERETURN rc; MQeExceptBlock exceptBlock; rc = mqe_uniqueValue(&exceptBlock, &confirmId); /* create the cryptor */ rc = mqeMARSCryptor_new(&exceptBLock, &mars); /* create an attribute using the cryptor */ rc = mqeMTrustAttribute_new(&exceptBLock, &attr, NULL, mars, NULL); /* open the private registry belonging to the sender */ rc = mqePrivateRegistry_new(&exceptBLock, &sendreg); rc = mqePrivateRegistry_activate(sendreg, &exceptBLock, MQeStrinh("Bruce1"), MQeString(".//MQeNode_PrivateRegistry"), MQeString("12345678"), MQeString("It_is_a_secret"), NULL, NULL); /* set the private registry in the attribute */ rc = mqeMTrustAttribute_setPrivateRegistry(attr, &exceptBLock, sendreg); /* set the target (recipient) name in the attribute */ rc = mqeMTrustAttribute_setTarget(attr, &exceptBLock, MQeString("Bruce8")); /* open a public registry to get the target's certificate */ rc = mqePublicRegistry_new(&exceptBLock, &pr); rc = mqePublicRegistry_activate(pr, &exceptBLock, MQeString("MQeNode_PublicRegistry"), MQeString(".//")); /* set the public registry in the attribute */ rc = mqeMTrustAttribute_setPublicRegistry(attr, &exceptBLock, pr); /* set a home server, which is used to find the certificate*/ /* if it is not already in the public registry */ rc = mqeMTrustAttribute_setHomeServer(attr, &exceptBLock, MQeString(MyHomeServer ":8082")); /* create the message */ rc = mqeMsgObject_new(&exceptBLock, &msObj); rc = mqeFields_putAscii(msgObj, &exceptBLock, MQeString("MsgData"), MQeString("0123456789abcdef...")); /* put the message using the attribute */ rc = mqeQueueManager_putMessage(newQM, &exceptBLock, targetQMgrName, targetQName, msgObj, attr, confirmId ); /*SIMPLE UNPROTECT FRAGMENT */ MQeMsgHNDL msgObj2; MQeMTrustAttributeHndl attr2; MQeMARSCryptorHndl mars; MQePrivateRegistryHndl getreg; MQePublicRegistryHndl pr; MQeInt64 confirmId2; MQERETURN rc; MQeExceptBlock exceptBlock; rc = mqe_uniqueValue(&exceptBLock, &confirmId); /* create the cryptor */ rc = mqeMARSCryptor_new(&exceptBLock, &mars); /* create an attribute using the cryptor */ rc = mqeMTrustAttribute_new(&exceptBLock,&attr2, NULL, mars, NULL); /* open the private registry belonging to the target */ rc = mqePrivateRegistry_new(&exceptBLock, &getreg); rc = mqePrivateRegistry_activate(getreg, &exceptBLock, MQeStrinh("Bruce8"), MQeString(".//MQeNode_PrivateRegistry"), MQeString("12345678"), MQeString("It_is_a_secret"), NULL, NULL); /* set the private registry in the attribute */ rc = mqeMTrustAttribute_setPrivateRegistry(attr2, &exceptBLock, getreg); /* open a public registry to get the sender's certificate */ rc = mqePublicRegistry_new(&exceptBLock, &pr); rc = mqePublicRegistry_activate(pr, &exceptBLock, MQeString("MQeNode_PublicRegistry"), MQeString(".//")); /* set the public registry in the attribute */ rc = mqeMTrustAttribute_setPublicRegistry(attr2, &exceptBLock, pr); /* set a home server, which is used to find the certificate*/ /* if it is not already in the public registry */ rc = mqeMTrustAttribute_setHomeServer(attr2, &exceptBLock, MQeString(MyHomeServer ":8082")); /* get the message using the attribute */ rc = mqeQueueManager_getMessage(newQM, &exceptBLock, &msgObj2, targetQMgrName, targetQName, NULL, attr2, confirmId2 );
The MQeMTrustAttribute digitally signs the message. This enables the recipient to validate the creator of the message, and ensures that the creator cannot later deny creating the message. This is known as non-repudiation. This process depends on the fact that only one public key (certificate) can validate the signature successfully, and this proves that the signature was created with the corresponding private key. The only way the alleged creator can deny creating the message is to claim that someone else had access to the private key.
When a message is created with the MQeMTrustAttribute, it uses the private key from the sender's private registry to create the digital signature and it stores the sender's name in the message. When the message is read (with the queue manager's getMessage() function), it uses the sender's public certificate to validate the digital signature. The message is read successfully only if the signature validates successfully, proving that the message was created by the entity whose name was stored in the message as the sender.
When the MQeMTrustAttribute is specified as a parameter to the queue manager's getMessage() function, the attribute validates the digital signature but by the time the message is returned to the user's application all the information relating to the signature has been discarded. If non-repudiation is important to you, you must keep a record of this information. The simplest way to do this is to keep a copy of the encrypted message, because that includes the digital signature. You can do this by using the getMessage() function without an attribute. This returns the encrypted message which you can then save, for example in a local queue. You can decrypt the message by applying the attribute to access the contents of the message.
The following pseudo-code fragment provides an example of how to save an encrypted message.
Saving a copy of an encrypted message
/*SIMPLE FRAGMENT TO SAVE ENCRYPTED MESSAGE*/ MQeMsgHndl msgObj2, tmpMsg1, tmpMsg2; MQeMTrustAttributeHndl attr2; MQeMARSCryptorHndl mars; MQePrivateRegistryHndl getreg; MQePublicRegistryHndl pr; MQeInt64 confirmId2, confirmId3; MQERETURN rc; MQeExceptBlock exceptBlock; rc = mqe_uniqueValue(&exceptBlock, &confirmId2); rc = mqe_uniqueValue(&exceptBlock, &confirmId3); /* read the encrypted message without an attribute */ rc = mqeQueueManager_getMessage(newQM, &exceptBlock, &tmpMsg1, targetQMgrName,targetQName, NULL, NULL, confirmId2 ); /* save the encrypted message - we cannot put it directly */ /* to another queue because of the origin queue manager */ /* data. Embed it in another message */ rc = mqeMsg_new(&exceptBlock, &tmpMsg2); rc = mqeFields_putFields(tmpMsg2, &exceptBlock, MQeTring("encryptedMsg"), tmpMsg1); rc = mqeQueueManager_putMessage(newQM, &exceptBlock, localQMgrName, archiveQName, tmpMsg2, NULL, confirmId3); /* now decrypt and read the message ... */ /* create the cryptor */ rc = mqeMARSCryptor_new(&exceptBlock, &mars); /* create an attribute using the cryptor */ rc = mqeMTrustAttribute_new(&exceptBlock, &attr2, NULL, mars, NULL); /* open the private registry belonging to the target */ rc = mqePrivateRegistry_new(&exceptBlock, &getreg); rc = mqePrivateRegistry_activate(getreg, &exceptBlock, MQeStrinh("Bruce8"), MQeString(".//MQeNode_PrivateRegistry"), MQeString("12345678"), MQeString("It_is_a_secret"), NULL, NULL); /* set the private registry in the attribute */ rc = mqeMTrustAttribute_setPrivateRegistry(attr2, &exceptBlock, getreg); /* open a public registry to get the sender's certificate */ rc = mqePublicRegistry_new(&exceptBlock, &pr); rc = mqePublicRegistry_activate(pr, &exceptBlock, MQeString("MQeNode_PublicRegistry"), MQeString(".//")); /* set the public registry in the attribute */ rc = mqeMTrustAttribute_setPublicRegistry(attr2, &exceptBlock, pr); /* set a home server, which is used to find the certificate*/ /* if it is not already in the public registry */ rc = mqeMTrustAttribute_setHomeServer(attr2, &exceptBlock, MQeString(MyHomeServer ":8082")); /* decrypt the message by unwrapping it */ rc = mqeMsg_unwrapMsgObject(tmpMsg1, &exceptBlock, msObj2, attr2);