Advertisement
Guest User

Untitled

a guest
Aug 16th, 2017
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.03 KB | None | 0 0
  1. #include "seccomon.h"
  2. #include "secoid.h"
  3. #include "secasn1.h"
  4. #include "pkcs11.h"
  5. #include "pk11func.h"
  6. #include "pk11sdr.h"
  7.  
  8. /*
  9.  * Data structure and template for encoding the result of an SDR operation
  10.  *  This is temporary.  It should include the algorithm ID of the encryption mechanism
  11.  */
  12. struct SDRResult
  13. {
  14.   SECItem keyid;
  15.   SECAlgorithmID alg;
  16.   SECItem data;
  17. };
  18. typedef struct SDRResult SDRResult;
  19.  
  20. ........
  21. ..........
  22. .............
  23. static unsigned char keyID[] = {
  24.   0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  25.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
  26. };
  27.  
  28. static SECItem keyIDItem = {
  29.   0,
  30.   keyID,
  31.   sizeof keyID
  32. };
  33.  
  34. ...............
  35. ........................
  36. ............................... some more code........
  37. /*
  38.  * PK11SDR_Encrypt
  39.  *  Encrypt a block of data using the symmetric key identified.  The result
  40.  *  is an ASN.1 (DER) encoded block of keyid, params and data.
  41.  */
  42. SECStatus
  43. PK11SDR_Encrypt(SECItem *keyid, SECItem *data, SECItem *result, void *cx)
  44. {
  45.   SECStatus rv = SECSuccess;
  46.   PK11SlotInfo *slot = 0;
  47.   PK11SymKey *key = 0;
  48.   SECItem *params = 0;
  49.   PK11Context *ctx = 0;
  50.   CK_MECHANISM_TYPE type;
  51.   SDRResult sdrResult;
  52.   SECItem paddedData;
  53.   SECItem *pKeyID;
  54.   PLArenaPool *arena = 0;
  55.  
  56.   /* Initialize */
  57.   paddedData.len = 0;
  58.   paddedData.data = 0;
  59.  
  60.   arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
  61.   if (!arena) { rv = SECFailure; goto loser; }
  62.  
  63.   /* 1. Locate the requested keyid, or the default key (which has a keyid)
  64.    * 2. Create an encryption context
  65.    * 3. Encrypt
  66.    * 4. Encode the results (using ASN.1)
  67.    */
  68.  
  69.   slot = PK11_GetInternalKeySlot();
  70.   if (!slot) { rv = SECFailure; goto loser; }
  71.  
  72.   /* Use triple-DES */
  73.   type = CKM_DES3_CBC;
  74.  
  75.   /*
  76.    * Login to the internal token before we look for the key, otherwise we
  77.    * won't find it.
  78.    */
  79.   rv = PK11_Authenticate(slot, PR_TRUE, cx);
  80.   if (rv != SECSuccess) goto loser;
  81.  
  82.   /* Find the key to use */
  83.   pKeyID = keyid;
  84.   if (pKeyID->len == 0) {
  85.       pKeyID = &keyIDItem;  /* Use default value */
  86.  
  87.       /* put in a course lock to prevent a race between not finding the
  88.        * key and creating  one.
  89.        */
  90.  
  91.       if (pk11sdrLock) PR_Lock(pk11sdrLock);
  92.  
  93.       /* Try to find the key */
  94.       key = PK11_FindFixedKey(slot, type, pKeyID, cx);
  95.      
  96.       /* If the default key doesn't exist yet, try to create it */
  97.       if (!key) key = PK11_GenDES3TokenKey(slot, pKeyID, cx);
  98.       if (pk11sdrLock) PR_Unlock(pk11sdrLock);
  99.   } else {
  100.       key = PK11_FindFixedKey(slot, type, pKeyID, cx);
  101.   }
  102.  
  103.   if (!key) { rv = SECFailure; goto loser; }
  104.  
  105.   params = PK11_GenerateNewParam(type, key);
  106.   if (!params) { rv = SECFailure; goto loser; }
  107.  
  108.   ctx = PK11_CreateContextBySymKey(type, CKA_ENCRYPT, key, params);
  109.   if (!ctx) { rv = SECFailure; goto loser; }
  110.  
  111.   rv = padBlock(data, PK11_GetBlockSize(type, 0), &paddedData);
  112.   if (rv != SECSuccess) goto loser;
  113.  
  114.   sdrResult.data.len = paddedData.len;
  115.   sdrResult.data.data = (unsigned char *)PORT_ArenaAlloc(arena, sdrResult.data.len);
  116.  
  117.   rv = PK11_CipherOp(ctx, sdrResult.data.data, (int*)&sdrResult.data.len, sdrResult.data.len,
  118.                      paddedData.data, paddedData.len);
  119.   if (rv != SECSuccess) goto loser;
  120.  
  121.   PK11_Finalize(ctx);
  122.  
  123.   sdrResult.keyid = *pKeyID;
  124.  
  125.   rv = PK11_ParamToAlgid(SEC_OID_DES_EDE3_CBC, params, arena, &sdrResult.alg);
  126.   if (rv != SECSuccess) goto loser;
  127.  
  128.   if (!SEC_ASN1EncodeItem(0, result, &sdrResult, template)) { rv = SECFailure; goto loser; }
  129.  
  130. loser:
  131.   SECITEM_ZfreeItem(&paddedData, PR_FALSE);
  132.   if (arena) PORT_FreeArena(arena, PR_TRUE);
  133.   if (ctx) PK11_DestroyContext(ctx, PR_TRUE);
  134.   if (params) SECITEM_ZfreeItem(params, PR_TRUE);
  135.   if (key) PK11_FreeSymKey(key);
  136.   if (slot) PK11_FreeSlot(slot);
  137.  
  138.   return rv;
  139. }
  140. ..........
  141. ......................
  142. ..............................some more code....
  143. /*
  144.  * PK11SDR_Decrypt
  145.  *  Decrypt a block of data produced by PK11SDR_Encrypt.  The key used is identified
  146.  *  by the keyid field within the input.
  147.  */
  148. SECStatus
  149. PK11SDR_Decrypt(SECItem *data, SECItem *result, void *cx)
  150. {
  151.   SECStatus rv = SECSuccess;
  152.   PK11SlotInfo *slot = 0;
  153.   PK11SymKey *key = 0;
  154.   CK_MECHANISM_TYPE type;
  155.   SDRResult sdrResult;
  156.   SECItem *params = 0;
  157.   SECItem possibleResult = { 0, NULL, 0 };
  158.   PLArenaPool *arena = 0;
  159.  
  160.   arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
  161.   if (!arena) { rv = SECFailure; goto loser; }
  162.  
  163.   /* Decode the incoming data */
  164.   memset(&sdrResult, 0, sizeof sdrResult);
  165.   rv = SEC_QuickDERDecodeItem(arena, &sdrResult, template, data);
  166.   if (rv != SECSuccess) goto loser;  /* Invalid format */
  167.  
  168.   /* Find the slot and key for the given keyid */
  169.   slot = PK11_GetInternalKeySlot();
  170.   if (!slot) { rv = SECFailure; goto loser; }
  171.  
  172.   rv = PK11_Authenticate(slot, PR_TRUE, cx);
  173.   if (rv != SECSuccess) goto loser;
  174.  
  175.   /* Get the parameter values from the data */
  176.   params = PK11_ParamFromAlgid(&sdrResult.alg);
  177.   if (!params) { rv = SECFailure; goto loser; }
  178.  
  179.   /* Use triple-DES (Should look up the algorithm) */
  180.   type = CKM_DES3_CBC;
  181.   key = PK11_FindFixedKey(slot, type, &sdrResult.keyid, cx);
  182.   if (!key) {
  183.     rv = SECFailure;  
  184.   } else {
  185.     rv = pk11Decrypt(slot, arena, type, key, params,
  186.             &sdrResult.data, result);
  187.   }
  188.  
  189.   /*
  190.    * if the pad value was too small (1 or 2), then it's statistically
  191.    * 'likely' that (1 in 256) that we may not have the correct key.
  192.    * Check the other keys for a better match. If we find none, use
  193.    * this result.
  194.    */
  195.   if (rv == SECWouldBlock) {
  196.     possibleResult = *result;
  197.   }
  198.  
  199.   /*
  200.    * handle the case where your key indicies may have been broken
  201.    */
  202.   if (rv != SECSuccess) {
  203.     PK11SymKey *keyList = PK11_ListFixedKeysInSlot(slot, NULL, cx);
  204.     PK11SymKey *testKey = NULL;
  205.     PK11SymKey *nextKey = NULL;
  206.  
  207.     for (testKey = keyList; testKey;
  208.                 testKey = PK11_GetNextSymKey(testKey)) {
  209.         rv = pk11Decrypt(slot, arena, type, testKey, params,
  210.                  &sdrResult.data, result);
  211.         if (rv == SECSuccess) {
  212.         break;
  213.         }
  214.         /* found a close match. If it's our first remember it */
  215.         if (rv == SECWouldBlock) {
  216.         if (possibleResult.data) {
  217.             /* this is unlikely but possible. If we hit this condition,
  218.              * we have no way of knowing which possibility to prefer.
  219.              * in this case we just match the key the application
  220.              * thought was the right one */
  221.             SECITEM_ZfreeItem(result, PR_FALSE);
  222.         } else {
  223.             possibleResult = *result;
  224.         }
  225.         }
  226.     }
  227.  
  228.     /* free the list */
  229.     for (testKey = keyList; testKey; testKey = nextKey) {
  230.         nextKey = PK11_GetNextSymKey(testKey);
  231.         PK11_FreeSymKey(testKey);
  232.     }
  233.   }
  234.  
  235.   /* we didn't find a better key, use the one with a small pad value */
  236.   if ((rv != SECSuccess) && (possibleResult.data)) {
  237.     *result = possibleResult;
  238.     possibleResult.data = NULL;
  239.     rv = SECSuccess;
  240.   }
  241.  
  242. loser:
  243.   if (arena) PORT_FreeArena(arena, PR_TRUE);
  244.   if (key) PK11_FreeSymKey(key);
  245.   if (params) SECITEM_ZfreeItem(params, PR_TRUE);
  246.   if (slot) PK11_FreeSlot(slot);
  247.   if (possibleResult.data) SECITEM_ZfreeItem(&possibleResult, PR_FALSE);
  248.  
  249.   return rv;
  250. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement