X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=gcrypt.c;h=8e73b3b2696f0aee501c6a317280067b885e3011;hp=ea1e7710d01c53f5fd300444970806715ad14241;hb=3ea5399aeec092dcdb9f039288f1e146aadbb2f7;hpb=466c9b7ef6663bcda1aeadf324f74187816da32a diff --git a/gcrypt.c b/gcrypt.c index ea1e7710..8e73b3b2 100644 --- a/gcrypt.c +++ b/gcrypt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Andre Noll + * Copyright (C) 2011 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -15,6 +15,7 @@ #include "crypt.h" #include "crypt_backend.h" #include "fd.h" +#include "base64.h" //#define GCRYPT_DEBUG 1 @@ -26,7 +27,7 @@ static void dump_buffer(const char *msg, unsigned char *buf, int len) { int i; - fprintf(stderr, "%s (%u bytes): ", msg, len); + fprintf(stderr, "%s (%d bytes): ", msg, len); for (i = 0; i < len; i++) fprintf(stderr, "%02x ", buf[i]); fprintf(stderr, "\n"); @@ -87,7 +88,7 @@ void init_random_seed_or_die(void) } /** S-expression for the public part of an RSA key. */ -#define RSA_PUBKEY_SEXP "(public-key (rsa (n %m) (e %m)))" +#define RSA_PUBKEY_SEXP "(public-key (rsa (n %m) (e %m)))" /** S-expression for a private RSA key. */ #define RSA_PRIVKEY_SEXP "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))" @@ -97,7 +98,7 @@ static void mgf1(unsigned char *seed, size_t seed_len, unsigned result_len, { gcry_error_t gret; gcry_md_hd_t handle; - size_t n;; + size_t n; unsigned char *md; unsigned char octet_string[4], *rp = result, *end = rp + result_len; @@ -212,7 +213,7 @@ static int decode_key(const char *key_file, const char *header_str, ret = mmap_full_file(key_file, O_RDONLY, &map, &map_size, NULL); if (ret < 0) - return ret; + goto out; ret = -E_KEY_MARKER; if (strncmp(map, header_str, strlen(header_str))) goto unmap; @@ -239,7 +240,6 @@ static int decode_key(const char *key_file, const char *header_str, key[j++] = begin[i]; } key[j] = '\0'; - //PARA_CRIT_LOG("key: %s\n", key); blob_size = key_size * 2; blob = para_malloc(blob_size); ret = base64_decode(key, blob, blob_size); @@ -258,6 +258,7 @@ unmap: free(blob); blob = NULL; } +out: *result = blob; return ret; } @@ -275,14 +276,14 @@ enum asn1_types { /* bit 6 has value 0 */ static inline bool is_primitive(unsigned char c) { - return ((c & (1<<6)) == 0); + return (c & (1<<6)) == 0; } static inline bool is_primitive_integer(unsigned char c) { if (!is_primitive(c)) return false; - return ((c & 0x1f) == ASN1_TYPE_INTEGER); + return (c & 0x1f) == ASN1_TYPE_INTEGER; } /* Bit 8 is zero (and bits 7-1 give the length) */ @@ -305,7 +306,7 @@ static int find_pubkey_bignum_offset(const unsigned char *data, int len) { const unsigned char *p = data, *end = data + len; - /* the whole thing istarts with one sequence */ + /* the whole thing starts with one sequence */ if (*p != ASN1_TYPE_SEQUENCE) return -E_ASN1_PARSE; p++; @@ -429,7 +430,7 @@ static int find_privkey_bignum_offset(const unsigned char *data, int len) if (p >= end) return -E_ASN1_PARSE; - /* Skip next integer */ + /* skip next integer */ if (*p != ASN1_TYPE_INTEGER) return -E_ASN1_PARSE; p++; @@ -583,6 +584,7 @@ static int get_asn_public_key(const char *key_file, struct asymmetric_key **resu } key = para_malloc(sizeof(*key)); key->sexp = sexp; + key->num_bytes = n_size; *result = key; ret = n_size; PARA_INFO_LOG("successfully read %u bit asn public key\n", n_size * 8); @@ -604,7 +606,7 @@ static int get_ssh_public_key(unsigned char *data, int size, gcry_sexp_t *result size_t nr_scanned, erroff, decoded_size; gcry_mpi_t e = NULL, n = NULL; - PARA_DEBUG_LOG("decoding %d byte public rsa-ssh key\n", size); + PARA_DEBUG_LOG("decoding %d byte public rsa-ssh key\n", size); if (size > INT_MAX / 4) return -ERRNO_TO_PARA_ERROR(EOVERFLOW); blob = para_malloc(2 * size); @@ -758,13 +760,13 @@ static int decode_rsa(gcry_sexp_t sexp, int key_size, unsigned char *outbuf, PARA_DEBUG_LOG("decrypted buffer before unpad (%d bytes):\n", key_size); - dump_buffer("non-unpadded decrypted buffer", oaep_buf, key_size);; + dump_buffer("non-unpadded decrypted buffer", oaep_buf, key_size); ret = unpad_oaep(oaep_buf, key_size, outbuf, nbytes); if (ret < 0) goto out_mpi_release; PARA_DEBUG_LOG("decrypted buffer after unpad (%zu bytes):\n", *nbytes); - dump_buffer("unpadded decrypted buffer", outbuf, *nbytes);; + dump_buffer("unpadded decrypted buffer", outbuf, *nbytes); ret = 1; out_mpi_release: gcry_mpi_release(out_mpi); @@ -781,6 +783,9 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf, gcry_sexp_t in, out, priv_key; size_t nbytes; + ret = check_key_file(key_file, true); + if (ret < 0) + return ret; PARA_INFO_LOG("decrypting %d byte input\n", inlen); /* key_file -> asymmetric key priv */ ret = get_private_key(key_file, &priv); @@ -912,11 +917,25 @@ struct stream_cipher { gcry_cipher_hd_t handle; }; -struct stream_cipher *sc_new(const unsigned char *data, int len) +struct stream_cipher *sc_new(const unsigned char *data, int len, + bool use_aes) { gcry_error_t gret; - struct stream_cipher *sc = para_malloc(sizeof(*sc)); + + if (use_aes) { + assert(len >= 2 * AES_CRT128_BLOCK_SIZE); + gret = gcry_cipher_open(&sc->handle, GCRY_CIPHER_AES128, + GCRY_CIPHER_MODE_CTR, 0); + assert(gret == 0); + gret = gcry_cipher_setkey(sc->handle, data, + AES_CRT128_BLOCK_SIZE); + assert(gret == 0); + gret = gcry_cipher_setctr(sc->handle, + data + AES_CRT128_BLOCK_SIZE, AES_CRT128_BLOCK_SIZE); + assert(gret == 0); + return sc; + } gret = gcry_cipher_open(&sc->handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0); if (gret) { @@ -937,35 +956,14 @@ void sc_free(struct stream_cipher *sc) free(sc); } -int sc_send_bin_buffer(struct stream_cipher_context *scc, char *buf, - size_t size) +void sc_crypt(struct stream_cipher *sc, struct iovec *src, struct iovec *dst) { + gcry_cipher_hd_t handle = sc->handle; gcry_error_t gret; - int ret; - unsigned char *tmp = para_malloc(size); - assert(size); - gret = gcry_cipher_encrypt(scc->send->handle, tmp, size, - (unsigned char *)buf, size); - assert(gret == 0); - ret = xwrite(scc->fd, (char *)tmp, size); - free(tmp); - return ret; -} - -int sc_recv_bin_buffer(struct stream_cipher_context *scc, char *buf, - size_t size) -{ - gcry_error_t gret; - ssize_t ret = recv(scc->fd, buf, size, 0); - - if (ret < 0) - ret = -ERRNO_TO_PARA_ERROR(errno); - if (ret <= 0) - return ret; /* perform in-place encryption */ - gret = gcry_cipher_encrypt(scc->recv->handle, (unsigned char *)buf, ret, + *dst = *src; + gret = gcry_cipher_encrypt(handle, src->iov_base, src->iov_len, NULL, 0); assert(gret == 0); - return ret; }