primeiter: New functions for iterating over small primes.
[u/mdw/catacomb] / key-pass.c
index 1b0997a..ab8e003 100644 (file)
@@ -7,7 +7,7 @@
  * (c) 1999 Straylight/Edgeware
  */
 
-/*----- Licensing notice --------------------------------------------------* 
+/*----- Licensing notice --------------------------------------------------*
  *
  * This file is part of Catacomb.
  *
  * it under the terms of the GNU Library General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
- * 
+ *
  * Catacomb is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Library General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Library General Public
  * License along with Catacomb; if not, write to the Free
  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -56,8 +56,8 @@
 
 /* --- @key_lock@ --- *
  *
- * Arguments:  @key_data *kt@ = destination block
- *             @key_data *k@ = source key data block
+ * Arguments:  @key_data **kt@ = where to store the destination pointer
+ *             @key_data *k@ = source key data block or null to use @*kt@
  *             @const void *e@ = secret to encrypt key with
  *             @size_t esz@ = size of the secret
  *
@@ -66,7 +66,7 @@
  * Use:                Encrypts a key data block using a secret.
  */
 
-void key_lock(key_data *kt, key_data *k, const void *e, size_t esz)
+void key_lock(key_data **kt, key_data *k, const void *e, size_t esz)
 {
   dstr d = DSTR_INIT;
   octet b[RMD160_HASHSZ * 2];
@@ -79,6 +79,7 @@ void key_lock(key_data *kt, key_data *k, const void *e, size_t esz)
 
   /* --- Sanity check --- */
 
+  if (k) key_incref(k); else k = *kt;
   assert(((void)"Key data is already encrypted",
          (k->e & KF_ENCMASK) != KENC_ENCRYPT));
 
@@ -88,8 +89,6 @@ void key_lock(key_data *kt, key_data *k, const void *e, size_t esz)
   rand_get(RAND_GLOBAL, d.buf, RMD160_HASHSZ);
   d.len += RMD160_HASHSZ * 2;
   key_encode(k, &d, 0);
-  if (k == kt)
-    key_destroy(k);
   m = (octet *)d.buf + RMD160_HASHSZ * 2;
   msz = d.len - RMD160_HASHSZ * 2;
 
@@ -119,14 +118,15 @@ void key_lock(key_data *kt, key_data *k, const void *e, size_t esz)
   /* --- Done --- */
 
   BURN(b);
-  key_encrypted(kt, d.buf, d.len);
+  *kt = key_newencrypted(0, d.buf, d.len);
+  key_drop(k);
   dstr_destroy(&d);
 }
 
 /* --- @key_unlock@ --- *
  *
- * Arguments:  @key_data *kt@ = target block
- *             @key_data *k@ = source key data block
+ * Arguments:  @key_data **kt@ = where to store the destination pointer
+ *             @key_data *k@ = source key data block or null to use @*kt@
  *             @const void *e@ = secret to decrypt the block with
  *             @size_t esz@ = size of the secret
  *
@@ -135,11 +135,13 @@ void key_lock(key_data *kt, key_data *k, const void *e, size_t esz)
  * Use:                Unlocks a key using a secret.
  */
 
-int key_unlock(key_data *kt, key_data *k, const void *e, size_t esz)
+int key_unlock(key_data **kt, key_data *k, const void *e, size_t esz)
 {
   octet b[RMD160_HASHSZ * 2];
   octet *p = 0;
   int rc;
+  int drop = 0;
+  key_data *kd;
   rmd160_mgfctx r;
   blowfish_cbcctx c;
   rmd160_mackey mk;
@@ -148,6 +150,7 @@ int key_unlock(key_data *kt, key_data *k, const void *e, size_t esz)
 
   /* --- Sanity check --- */
 
+  if (!k) { k = *kt; drop = 1; }
   assert(((void)"Key data isn't encrypted",
          (k->e & KF_ENCMASK) == KENC_ENCRYPT));
 
@@ -191,16 +194,16 @@ int key_unlock(key_data *kt, key_data *k, const void *e, size_t esz)
 
   /* --- Decode the key data into the destination buffer --- */
 
-  if (k == kt)
-    key_destroy(k);
-  if (key_decode(p, sz, kt)) {
+  if ((kd = key_decode(p, sz)) == 0) {
     rc = KERR_MALFORMED;
     goto fail;
   }
+  *kt = kd;
 
   /* --- Done --- */
 
   xfree(p);
+  if (drop) key_drop(k);
   return (0);
 
   /* --- Tidy up if things went wrong --- */
@@ -213,16 +216,16 @@ fail:
 
 /* --- @key_plock@ --- *
  *
- * Arguments:  @const char *tag@ = tag to use for passphrase
- *             @key_data *k@ = source key data block
- *             @key_data *kt@ = target key data block
+ * Arguments:  @key_data **kt@ = where to store the destination pointer
+ *             @key_data *k@ = source key data block or null to use @*kt@
+ *             @const char *tag@ = tag to use for passphrase
  *
  * Returns:    Zero if successful, a @KERR@ error code on failure.
  *
  * Use:                Locks a key by encrypting it with a passphrase.
  */
 
-int key_plock(const char *tag, key_data *k, key_data *kt)
+int key_plock(key_data **kt, key_data *k, const char *tag)
 {
   char buf[256];
 
@@ -235,16 +238,16 @@ int key_plock(const char *tag, key_data *k, key_data *kt)
 
 /* --- @key_punlock@ --- *
  *
- * Arguments:  @const char *tag@ = tag to use for passphrase
- *             @key_data *k@ = source key data block
- *             @key_data *kt@ = target key data block
+ * Arguments:  @key_data **kt@ = where to store the destination pointer
+ *             @key_data *k@ = source key data block or null to use @*kt@
+ *             @const char *tag@ = tag to use for passphrase
  *
  * Returns:    Zero if it worked, a @KERR_@ error code on failure.
  *
  * Use:                Unlocks a passphrase-locked key.
  */
 
-int key_punlock(const char *tag, key_data *k, key_data *kt)
+int key_punlock(key_data **kt, key_data *k, const char *tag)
 {
   char buf[256];
   int rc;
@@ -253,7 +256,7 @@ int key_punlock(const char *tag, key_data *k, key_data *kt)
     return (KERR_IO);
   rc = key_unlock(kt, k, buf, strlen(buf));
   BURN(buf);
-  if (rc == KERR_BADPASS || k == kt)
+  if (rc == KERR_BADPASS || !k)
     passphrase_cancel(tag);
   return (rc);
 }