int Pk11StoreGetPin(char **out, Pk11PinStore *store) { int err = PIN_SUCCESS; unsigned char *plain; SECStatus rv = SECSuccess; PK11Context *ctx = 0; int outLen; do { plain = (unsigned char *)malloc(store->length); if (!plain) { err = PIN_NOMEMORY; break; } ctx = PK11_CreateContextBySymKey(store->mech->type, CKA_DECRYPT, store->key, store->params); if (!ctx) { err = PIN_SYSTEMERROR; break; } rv = PK11_CipherOp(ctx, plain, &outLen, store->length, store->crypt, store->length); if (rv) break; rv = PK11_Finalize(ctx); if (rv) break; } while(0); if (ctx) PK11_DestroyContext(ctx, PR_TRUE); if (rv) { err = PIN_SYSTEMERROR; memset(plain, 0, store->length); free(plain); plain = 0; } *out = (char *)plain; return err; }
SVRCOREError SVRCORE_Pk11StoreGetPin(char **out, SVRCOREPk11PinStore *store) { SVRCOREError err = SVRCORE_Success; unsigned char *plain; SECStatus rv; PK11Context *ctx = 0; int outLen; do { plain = (unsigned char *)malloc(store->length); if (!plain) { err = SVRCORE_NoMemory_Error; break; } ctx = PK11_CreateContextBySymKey(store->mech->type, CKA_DECRYPT, store->key, store->params); if (!ctx) { err = SVRCORE_System_Error; break; } rv = PK11_CipherOp(ctx, plain, &outLen, store->length, store->crypt, store->length); if (rv) break; rv = PK11_Finalize(ctx); if (rv) break; } while(0); if (ctx) PK11_DestroyContext(ctx, PR_TRUE); if (rv) { err = SVRCORE_System_Error; memset(plain, 0, store->length); free(plain); plain = 0; } *out = (char *)plain; return err; }
/* * CreatePk11PinStore */ int CreatePk11PinStore(Pk11PinStore **out, const char *tokenName, const char *pin) { int err = PIN_SUCCESS; Pk11PinStore *store; do { store = (Pk11PinStore*)malloc(sizeof(Pk11PinStore)); if (store == 0) { err = PIN_NOMEMORY; break; } /* Low-level init */ store->key = 0; store->params = 0; store->crypt = 0; /* Use the tokenName to find a PKCS11 slot */ store->slot = PK11_FindSlotByName((char *)tokenName); if (store->slot == 0) { err = PIN_NOSUCHTOKEN; break; } /* Check the password/PIN. This allows access to the token */ { SECStatus rv = PK11_CheckUserPassword(store->slot, (char *)pin); if (rv == SECSuccess) ; else if (rv == SECWouldBlock) { /* NSS returns a blocking error when the pin is wrong */ err = PIN_INCORRECTPW; break; } else { err = PIN_SYSTEMERROR; break; } } /* Find the mechanism that this token can do */ { const mech_item *tp; store->mech = 0; for(tp = table;tp < &table[MECH_TABLE_SIZE];tp++) { if (PK11_DoesMechanism(store->slot, tp->type)) { store->mech = (mech_item *)tp; break; } } /* Default to a mechanism (probably on the internal token */ if (store->mech == 0) { store->mech = &dflt_mech; } } /* Generate a key and parameters to do the encryption */ #if NSS_VMAJOR >= 3 && (NSS_VMINOR <= 9 || (NSS_VMINOR <= 10 && NSS_VPATCH == 0)) store->key = PK11_KeyGen(store->slot, store->mech->type, 0, 0, 0); #else store->key = PK11_TokenKeyGenWithFlags(store->slot, store->mech->type, NULL, 0, NULL, CKF_ENCRYPT|CKF_DECRYPT, PR_FALSE, NULL); #endif if (store->key == 0) { /* PR_SetError(xxx); */ err = PIN_SYSTEMERROR; break; } store->params = PK11_GenerateNewParam(store->mech->type, store->key); if (store->params == 0) { err = PIN_SYSTEMERROR; break; } /* Compute the size of the encrypted data including necessary padding */ { int blocksize = PK11_GetBlockSize(store->mech->type, 0); store->length = strlen(pin)+1; /* Compute padded size - 0 means stream cipher */ if (blocksize != 0) { store->length += blocksize - (store->length % blocksize); } store->crypt = (unsigned char *)malloc(store->length); if (!store->crypt) { err = PIN_NOMEMORY; break; } } /* Encrypt */ { unsigned char *plain; PK11Context *ctx; SECStatus rv; int outLen; plain = (unsigned char *)malloc(store->length); if (!plain) { err = PIN_NOMEMORY; break; } /* Pad with 0 bytes */ memset(plain, 0, store->length); strcpy((char *)plain, pin); ctx = PK11_CreateContextBySymKey(store->mech->type, CKA_ENCRYPT, store->key, store->params); if (!ctx) { err = PIN_SYSTEMERROR; break; } do { rv = PK11_CipherOp(ctx, store->crypt, &outLen, store->length, plain, store->length); if (rv) break; rv = PK11_Finalize(ctx); } while(0); PK11_DestroyContext(ctx, PR_TRUE); memset(plain, 0, store->length); free(plain); if (rv) err = PIN_SYSTEMERROR; } } while(0); if (err) { DestroyPk11PinStore(store); store = 0; } *out = store; return err; }
/* * SVRCORE_CreatePk11PinStore */ SVRCOREError SVRCORE_CreatePk11PinStore( SVRCOREPk11PinStore **out, const char *tokenName, const char *pin) { SVRCOREError err; SVRCOREPk11PinStore *store; do { err = SVRCORE_Success; store = (SVRCOREPk11PinStore*)malloc(sizeof *store); if (store == 0) { err = SVRCORE_NoMemory_Error; break; } /* Low-level init */ store->slot = 0; store->key = 0; store->params = 0; store->crypt = 0; /* Use the tokenName to find a PKCS11 slot */ store->slot = PK11_FindSlotByName((char *)tokenName); if (store->slot == 0) { err = SVRCORE_NoSuchToken_Error; break; } /* Check the password/PIN. This allows access to the token */ { SECStatus rv = PK11_CheckUserPassword(store->slot, (char *)pin); if (rv == SECSuccess) ; else if (rv == SECWouldBlock) { err = SVRCORE_IncorrectPassword_Error; break; } else { err = SVRCORE_System_Error; break; } } /* Find the mechanism that this token can do */ { const mech_item *tp; store->mech = 0; for(tp = table;tp < &table[MECH_TABLE_SIZE];tp++) { if (PK11_DoesMechanism(store->slot, tp->type)) { store->mech = tp; break; } } /* Default to a mechanism (probably on the internal token */ if (store->mech == 0) store->mech = &dflt_mech; } /* Generate a key and parameters to do the encryption */ store->key = PK11_TokenKeyGenWithFlags(store->slot, store->mech->type, 0, 0, 0, CKF_ENCRYPT|CKF_DECRYPT, 0, 0); if (store->key == 0) { /* PR_SetError(xxx); */ err = SVRCORE_System_Error; break; } store->params = PK11_GenerateNewParam(store->mech->type, store->key); if (store->params == 0) { err = SVRCORE_System_Error; break; } /* Compute the size of the encrypted data including necessary padding */ { int blocksize = PK11_GetBlockSize(store->mech->type, 0); store->length = strlen(pin)+1; /* Compute padded size - 0 means stream cipher */ if (blocksize != 0) { store->length += blocksize - (store->length % blocksize); } store->crypt = (unsigned char *)malloc(store->length); if (!store->crypt) { err = SVRCORE_NoMemory_Error; break; } } /* Encrypt */ { unsigned char *plain; PK11Context *ctx; SECStatus rv; int outLen; plain = (unsigned char *)malloc(store->length); if (!plain) { err = SVRCORE_NoMemory_Error; break; } /* Pad with 0 bytes */ memset(plain, 0, store->length); strcpy((char *)plain, pin); ctx = PK11_CreateContextBySymKey(store->mech->type, CKA_ENCRYPT, store->key, store->params); if (!ctx) { err = SVRCORE_System_Error; break; } do { rv = PK11_CipherOp(ctx, store->crypt, &outLen, store->length, plain, store->length); if (rv) break; rv = PK11_Finalize(ctx); } while(0); PK11_DestroyContext(ctx, PR_TRUE); memset(plain, 0, store->length); free(plain); if (rv) err = SVRCORE_System_Error; } } while(0); if (err) { SVRCORE_DestroyPk11PinStore(store); store = 0; } *out = store; return err; }
TPS_PUBLIC PRStatus Util::ComputeMAC(PK11SymKey *key, Buffer &x_input, const Buffer &icv, Buffer &output) { PRStatus rv = PR_SUCCESS; PK11Context *context = NULL; // NetkeyICV temp; unsigned char result[8]; int i; SECStatus s; int len; #ifdef USE_DESMAC CK_ULONG macLen = sizeof result; SECItem params = { siBuffer, (unsigned char *)&macLen, sizeof macLen }; #endif static SECItem noParams = { siBuffer, 0, 0 }; static unsigned char macPad[] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; BYTE *input = (BYTE *) x_input; int inputLen = x_input.size(); #ifdef USE_DESMAC context = PK11_CreateContextBySymKey(CKM_DES3_MAC_GENERAL, CKA_SIGN, key, ¶ms); if (!context) { rv = PR_FAILURE; goto done; } s = PK11_DigestBegin(context); if (s != SECSuccess) { rv = PR_FAILURE; goto done; } s = PK11_DigestOp(context, icv, 8); if (s != SECSuccess) { rv = PR_FAILURE; goto done; } while(inputLen >= 8) { s = PK11_DigestOp(context, input, 8); if (s != SECSuccess) { rv = PR_FAILURE; goto done; } input += 8; inputLen -= 8; } for (i = 0;i < inputLen;i++) { result[i] = input[i]; } input = macPad; for(;i < 8;i++) { result[i] = *input++; } s = PK11_DigestOp(context, result, sizeof result); if (s != SECSuccess) { rv = PR_FAILURE; goto done; } s = PK11_DigestFinal(context, output, (unsigned int *)&len, sizeof output); if (1 != SECSuccess) { rv = PR_FAILURE; goto done; } #else context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key, &noParams); if (!context) { rv = PR_FAILURE; goto done; } memcpy(result, icv, sizeof result); /* Process whole blocks */ while(inputLen >= 8) { for(i = 0;i < 8;i++) { result[i] ^= input[i]; } s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result); if (s != SECSuccess) { rv = PR_FAILURE; goto done; } if (len != sizeof result) /* assert? */ { //PR_SetError(PR_UNKNOWN_ERROR, 0); rv = PR_FAILURE; goto done; } input += 8; inputLen -= 8; } /* * Fold in remaining data (if any) * Set i to number of bytes processed */ for(i = 0;i < inputLen;i++) { result[i] ^= input[i]; } /* * Fill remainder of last block. There * will be at least one byte handled here. */ input = macPad; while(i < 8) { result[i] ^= *input++; i++; } s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result); if (s != SECSuccess) { rv = PR_FAILURE; goto done; } if (len != sizeof result) { //PR_SetError(PR_UNKNOWN_ERROR, 0); rv = PR_FAILURE; goto done; } output.replace(0, result, sizeof result); #endif done: if( context != NULL ) { PK11_Finalize( context ); PK11_DestroyContext( context, PR_TRUE ); context = NULL; } memset(result, 0, sizeof result); return rv; } /* ComputeMAC */