/*
- * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
-/** \file crypt_common.c Crypto functions independent of the implementation. */
+/** \file crypt_common.c Crypto functions independent of openssl/libgcrypt. */
#include <regex.h>
-#include <stdbool.h>
#include "para.h"
#include "error.h"
#include "string.h"
-#include "crypt_backend.h"
#include "crypt.h"
+#include "crypt_backend.h"
+/** If the key begins with this text, we treat it as an ssh key. */
#define KEY_TYPE_TXT "ssh-rsa"
/**
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '=';
-/*
+
+/**
+ * base64-decode a buffer.
+ *
+ * \param src The buffer to decode.
+ * \param target Result is stored here.
+ * \param targsize Number of bytes of \a target.
+ *
* Skips all whitespace anywhere. Converts characters, four at a time, starting
* at (or after) src from base - 64 numbers into three 8 bit bytes in the
- * target area. it returns the number of data bytes stored at the target, or -E_BASE64
- * on error.
+ * target area.
+ *
+ * \return The number of data bytes stored at the target, -E_BASE64 on errors.
*/
int base64_decode(char const *src, unsigned char *target, size_t targsize)
{
break;
pos = strchr(Base64, ch);
- if (pos == 0) /* A non-base64 character. */
+ if (pos == NULL) /* A non-base64 character. */
return -E_BASE64;
switch (state) {
case 0:
- if (target) {
- if (tarindex >= targsize)
- return -E_BASE64;
- target[tarindex] = (pos - Base64) << 2;
- }
+ if (tarindex >= targsize)
+ return -E_BASE64;
+ target[tarindex] = (pos - Base64) << 2;
state = 1;
break;
case 1:
- if (target) {
- if (tarindex + 1 >= targsize)
- return -E_BASE64;
- target[tarindex] |= (pos - Base64) >> 4;
- target[tarindex+1] = ((pos - Base64) & 0x0f)
- << 4 ;
- }
+ if (tarindex + 1 >= targsize)
+ return -E_BASE64;
+ target[tarindex] |= (pos - Base64) >> 4;
+ target[tarindex + 1] = ((pos - Base64) & 0x0f) << 4;
tarindex++;
state = 2;
break;
case 2:
- if (target) {
- if (tarindex + 1 >= targsize)
- return -E_BASE64;
- target[tarindex] |= (pos - Base64) >> 2;
- target[tarindex+1] = ((pos - Base64) & 0x03)
- << 6;
- }
+ if (tarindex + 1 >= targsize)
+ return -E_BASE64;
+ target[tarindex] |= (pos - Base64) >> 2;
+ target[tarindex + 1] = ((pos - Base64) & 0x03) << 6;
tarindex++;
state = 3;
break;
case 3:
- if (target) {
- if (tarindex >= targsize)
- return -E_BASE64;
- target[tarindex] |= (pos - Base64);
- }
+ if (tarindex >= targsize)
+ return -E_BASE64;
+ target[tarindex] |= pos - Base64;
tarindex++;
state = 0;
break;
* zeros. If we don't check them, they become a
* subliminal channel.
*/
- if (target && target[tarindex] != 0)
+ if (target[tarindex] != 0)
return -E_BASE64;
}
} else {
return tarindex;
}
+/**
+ * uudecode a buffer.
+ *
+ * \param src The buffer to decode.
+ * \param target Result buffer.
+ * \param targsize The length of \a target in bytes.
+ *
+ * This is just a simple wrapper for base64_decode() which strips whitespace.
+ *
+ * \return The return value of the underlying call to base64_decode().
+ */
int uudecode(const char *src, unsigned char *target, size_t targsize)
{
int len;
return len;
}
-/*
- * Can not use the inline functions of portable_io.h here because the byte
- * order is different.
+/**
+ * Read a 4-byte number from a buffer in big-endian format.
+ *
+ * \param vp The buffer.
+ *
+ * The byte-order of the buffer is expected to be big-endian, unlike read_u32()
+ * of portable_io.h which expects little endian.
+ *
+ * \return The 32 bit number given by \a vp.
*/
uint32_t read_ssh_u32(const void *vp)
{
return v;
}
+/**
+ * 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..).
+ *
+ * \return The number of bytes to skip until the start of the first encoded
+ * number (usually 11).
+ */
int check_ssh_key_header(const unsigned char *blob, int blen)
{
const unsigned char *p = blob, *end = blob + blen;
return 4 + rlen;
}
+/**
+ * Check existence and permissions of a key file.
+ *
+ * \param file The path of the key file.
+ * \param private_key Whether this is a private key.
+ *
+ * This checks whether the file exists. If it is a private key, we additionally
+ * check that the permissions are restrictive enough. It is considered an error
+ * if we own the file and it is readable for others.
+ *
+ * \return Standard.
+ */
int check_key_file(const char *file, bool private_key)
{
struct stat st;
return 1;
}
-/**
- * Convert a hash value to ascii format.
- *
- * \param hash the hash value.
- * \param asc Result pointer.
- *
- * \a asc must point to an area of at least 2 * \p HASH_SIZE + 1 bytes which
- * will be filled by the function with the ascii representation of the hash
- * value given by \a hash, and a terminating \p NULL byte.
- */
void hash_to_asc(unsigned char *hash, char *asc)
{
int i;
asc[2 * HASH_SIZE] = '\0';
}
-/**
- * Compare two hashes.
- *
- * \param h1 Pointer to the first hash value.
- * \param h2 Pointer to the second hash value.
- *
- * \return 1, -1, or zero, depending on whether \a h1 is greater than,
- * less than or equal to h2, respectively.
- */
int hash_compare(unsigned char *h1, unsigned char *h2)
{
int i;
}
return 0;
}
-
-/**
- * Receive a buffer, decrypt it and write terminating NULL byte.
- *
- * \param scc The context.
- * \param buf The buffer to write the decrypted data to.
- * \param size The size of \a buf.
- *
- * Read at most \a size - 1 bytes from file descriptor given by \a scc, decrypt
- * the received data and write a NULL byte at the end of the decrypted data.
- *
- * \return The return value of the underlying call to \ref
- * sc_recv_bin_buffer().
- */
-int sc_recv_buffer(struct stream_cipher_context *scc, char *buf, size_t size)
-{
- int n;
-
- assert(size);
- n = sc_recv_bin_buffer(scc, buf, size - 1);
- if (n >= 0)
- buf[n] = '\0';
- else
- *buf = '\0';
- return n;
-}
-
-/**
- * Encrypt and send a \p NULL-terminated buffer.
- *
- * \param scc The context.
- * \param buf The buffer to send.
- *
- * \return The return value of the underyling call to sc_send_bin_buffer().
- */
-int sc_send_buffer(struct stream_cipher_context *scc, char *buf)
-{
- return sc_send_bin_buffer(scc, buf, strlen(buf));
-}
-
-/**
- * Format, encrypt and send a buffer.
- *
- * \param scc The context.
- * \param fmt A format string.
- *
- * \return The return value of the underyling call to sc_send_buffer().
- */
-__printf_2_3 int sc_send_va_buffer(struct stream_cipher_context *scc,
- const char *fmt, ...)
-{
- char *msg;
- int ret;
-
- PARA_VSPRINTF(fmt, msg);
- ret = sc_send_buffer(scc, msg);
- free(msg);
- return ret;
-}