summaryrefslogtreecommitdiffstats
path: root/security/nss/doc/rst/legacy/nss_sample_code/nss_sample_code_sample6/index.rst
diff options
context:
space:
mode:
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.rst153
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