mixer.c: Fix doxygen \file description.
[paraslash.git] / crypt_common.c
index 08361b27104d6a4658e151259ba6f0ae585205c0..235b8b8d3e398551fc28bfbc746349c5dc8f6f1c 100644 (file)
 #include "crypt.h"
 #include "crypt_backend.h"
 #include "portable_io.h"
+#include "fd.h"
+#include "base64.h"
 
 /** If the key begins with this text, we treat it as an ssh key. */
 #define KEY_TYPE_TXT "ssh-rsa"
 
-/**
- * Check if given buffer starts with a ssh rsa key signature.
- *
- * \param data The buffer.
- * \param size Number of data bytes.
+/*
+ * Check if the given buffer starts with an ssh rsa key signature.
  *
- * \return Number of header bytes to be skipped on success, zero if
- * ssh rsa signature was not found.
+ * Returns number of header bytes to be skipped on success, zero if no ssh rsa
+ * signature was found.
  */
-size_t is_ssh_rsa_key(char *data, size_t size)
+static size_t is_ssh_rsa_key(char *data, size_t size)
 {
        char *cp;
 
@@ -42,20 +41,13 @@ size_t is_ssh_rsa_key(char *data, size_t size)
        return cp - data;
 }
 
-/**
- * Sanity checks for the header of an ssh key.
- *
- * \param blob The buffer.
- * \param blen The number of bytes of \a blob.
+/*
+ * Perform some sanity checks on the decoded ssh key.
  *
- * This performs some checks to make sure we really have an ssh key. It also
- * computes the offset in bytes of the start of the key values (modulus,
- * exponent..).
- *
- * \return The number of bytes to skip until the start of the first encoded
- * number (usually 11).
+ * This function returns the size of the header. Usually, the header is 11
+ * bytes long: four bytes for the length field, and the string "ssh-rsa".
  */
-int check_ssh_key_header(const unsigned char *blob, int blen)
+static int check_ssh_key_header(const unsigned char *blob, int blen)
 {
        const unsigned char *p = blob, *end = blob + blen;
        uint32_t rlen;
@@ -76,6 +68,51 @@ int check_ssh_key_header(const unsigned char *blob, int blen)
        return 4 + rlen;
 }
 
+/**
+ * Perform sanity checks and base64-decode an ssh-rsa key.
+ *
+ * \param filename The public key file (usually id_rsa.pub).
+ * \param blob Pointer to base64-decoded blob is returned here.
+ * \param decoded_size The size of the decoded blob.
+ *
+ * The memory pointed at by the returned blob pointer has to be freed by the
+ * caller.
+ *
+ * \return On success, the offset in bytes of the start of the key values
+ * (modulus, exponent..). This is the number of bytes to skip from the blob
+ * until the start of the first encoded number. On failure, a negative error
+ * code is returned.
+ *
+ * \sa \ref uudecode().
+ */
+int decode_ssh_key(const char *filename, unsigned char **blob,
+               size_t *decoded_size)
+{
+       int ret, ret2;
+       void *map;
+       size_t map_size;
+
+       ret = mmap_full_file(filename, O_RDONLY, &map, &map_size, NULL);
+       if (ret < 0)
+               return ret;
+       ret = is_ssh_rsa_key(map, map_size);
+       if (ret == 0) {
+               ret = -E_SSH_PARSE;
+               goto unmap;
+       }
+       ret = uudecode(map + ret, map_size - ret, (char **)blob, decoded_size);
+       if (ret < 0)
+               goto unmap;
+       ret = check_ssh_key_header(*blob, *decoded_size);
+       if (ret < 0)
+               goto unmap;
+unmap:
+       ret2 = para_munmap(map, map_size);
+       if (ret >= 0 && ret2 < 0)
+               ret = ret2;
+       return ret;
+}
+
 /**
  * Check existence and permissions of a private key file.
  *