diff options
Diffstat (limited to 'security/nss/doc/rst/legacy/nss_sample_code/nss_sample_code_sample6/index.rst')
-rw-r--r-- | security/nss/doc/rst/legacy/nss_sample_code/nss_sample_code_sample6/index.rst | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/security/nss/doc/rst/legacy/nss_sample_code/nss_sample_code_sample6/index.rst b/security/nss/doc/rst/legacy/nss_sample_code/nss_sample_code_sample6/index.rst new file mode 100644 index 0000000000..b194873bc4 --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_sample_code/nss_sample_code_sample6/index.rst @@ -0,0 +1,153 @@ +.. _mozilla_projects_nss_nss_sample_code_nss_sample_code_sample6: + +NSS Sample Code sample6 +======================= + +.. _nss_sample_code_6_persistent_symmetric_keys_in_nss_database: + +`NSS Sample Code 6: Persistent Symmetric Keys in NSS database <#nss_sample_code_6_persistent_symmetric_keys_in_nss_database>`__ +------------------------------------------------------------------------------------------------------------------------------- + +.. container:: + + .. code:: + + /* Example code to illustrate generation of a secret symmetric key ring + * that PERSISTS in the NSS database. The symmetric keys can then be used + * without ever exposing them in the clear. + * + * To encrypt, you need the id of the key to use. + * To decrypt, you need the ciphertext and the id of the key that was used + * to encrypt + * + * Before running this example, create the NSS database + * certutil -N -d . + * (enter "test" when prompted for password) + */ + + + #include "nss.h" + #include "pk11pub.h" + + /* the key id can be any sequence of bytes. this example happens to use an + * integer */ + void genkey(int id); + + /* this callback is responsible for returning the password to the NSS + * key database. for example purposes, this function hardcodes the password. + * In a real app, this function should obtain the password using secure means + * such as prompting an operator, or retrieving it over a secure communication + * channel + */ + char *passwdcb(PK11SlotInfo *info, PRBool retry, void *arg); + + + int main(int argc, char **argv) + { + SECStatus rv; + + /* Initialize NSS */ + PK11_SetPasswordFunc(passwdcb); + + /* The NSS db must be initialized read-write since we'll be creating + * keys in it. Once keys are generated, it can be opened without read-write + * subsequently (NSS_Init). + */ + rv = NSS_InitReadWrite("."); + if (rv != SECSuccess) + { + fprintf(stderr, "NSS initialization failed (err %d)\n", + PR_GetError()); + exit(1); + } + + /* generate a key with id 1. should succeed on first run on a fresh db, + * should fail on successive runs because key with that id already exists */ + genkey(1); + + /* generate a key with id 2. should succeed on first run on a fresh db, + * should fail on successive runs because key with that id already exists */ + genkey(2); + + /* generate a key with id 1 - this will fail because key with that id + * already exists */ + genkey(1); + } + + + void genkey(int id) + { + PK11SlotInfo* slot = NULL; + PK11SymKey* key = NULL; + SECItem keyiditem; + int keyid[1]; + CK_MECHANISM_TYPE cipherMech; + + /* using CKM_AES_CBC_PAD mechanism for example */ + cipherMech = CKM_AES_CBC_PAD; + + slot = PK11_GetInternalKeySlot(); + /* slot = PK11_GetBestSlot(cipherMech, NULL); didn't work. + * Error code: token is read-only. ?? + */ + if (slot == NULL) + { + fprintf(stderr, "Unable to find security device (err %d)\n", + PR_GetError()); + return; + } + + keyid[0] = id; + keyiditem.type = siBuffer; + keyiditem.data = (void *)keyid; + keyiditem.len = sizeof(keyid[0]); + + /* Note: keysize must be 0 for fixed key-length algorithms like DES. + * Since we're using AES in this example, we're specifying + * one of the valid keysizes (16, 24, 32) + */ + key = PK11_TokenKeyGen(slot, cipherMech, 0, 32 /*keysize*/, + &keyiditem, PR_TRUE, 0); + if (key == NULL) + { + fprintf(stderr, "PK11_TokenKeyGen failed (err %d)\n", + PR_GetError()); + PK11_FreeSlot(slot); + return; + } + + fprintf(stderr, "key length of generated key is %d\n", + PK11_GetKeyLength(key)); + fprintf(stderr, "mechanism of key is %d (asked for %d)\n", + PK11_GetMechanism(key), cipherMech); + + PK11_FreeSymKey(key); + + + key = PK11_FindFixedKey(slot, cipherMech, &keyiditem, 0); + if (key == NULL) + { + fprintf(stderr, "PK11_FindFixedKey failed (err %d)\n", + PR_GetError()); + PK11_FreeSlot(slot); + return; + } + + fprintf(stderr, "Found key!\n"); + fprintf(stderr, "key length of generated key is %d\n", + PK11_GetKeyLength(key)); + fprintf(stderr, "mechanism of key is %d (asked for %d)\n", + PK11_GetMechanism(key), cipherMech); + + PK11_FreeSymKey(key); + + PK11_FreeSlot(slot); + } + + char *passwdcb(PK11SlotInfo *info, PRBool retry, void *arg) + { + if (!retry) + return PL_strdup("test"); + else + return NULL; + }
\ No newline at end of file |