X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=crypt_common.c;h=235b8b8d3e398551fc28bfbc746349c5dc8f6f1c;hp=ac8564ebafbede53415866446ecfc78549a987de;hb=bab99bab677988723afe14a7d680e6d5cc7ddda4;hpb=177ea8ea46918a925c0d2d8a07e7fbe9f478a40c diff --git a/crypt_common.c b/crypt_common.c index ac8564eb..235b8b8d 100644 --- a/crypt_common.c +++ b/crypt_common.c @@ -1,8 +1,4 @@ -/* - * Copyright (C) 2005 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ +/* Copyright (C) 2005 Andre Noll , see file COPYING. */ /** \file crypt_common.c Crypto functions independent of openssl/libgcrypt. */ @@ -14,20 +10,19 @@ #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; @@ -46,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. - * - * 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; @@ -80,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. *