-/*
- * Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
/** \file crypt_common.c Crypto functions independent of openssl/libgcrypt. */
#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;
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.
- *
- * 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..).
+/*
+ * Perform some sanity checks on the decoded ssh key.
*
- * \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;
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.
*