uoff_t ftr, pos;
enum io_stream_encrypt_flags flags;
- unsigned char *iv; /* original iv, in case seeking is done, future feature */
+ /* original iv, in case seeking is done, future feature */
+ unsigned char *iv;
struct dcrypt_context_symmetric *ctx_sym;
struct dcrypt_context_hmac *ctx_mac;
enum decrypt_istream_format format;
};
-enum decrypt_istream_format i_stream_encrypt_get_format(const struct istream *input)
+enum decrypt_istream_format
+i_stream_encrypt_get_format(const struct istream *input)
{
return ((const struct decrypt_istream*)input->real_stream)->format;
}
-enum io_stream_encrypt_flags i_stream_encrypt_get_flags(const struct istream *input)
+enum io_stream_encrypt_flags
+i_stream_encrypt_get_flags(const struct istream *input)
{
return ((const struct decrypt_istream*)input->real_stream)->flags;
}
-static
-ssize_t i_stream_decrypt_read_header_v1(struct decrypt_istream *stream,
- const unsigned char *data, size_t mlen)
+static ssize_t
+i_stream_decrypt_read_header_v1(struct decrypt_istream *stream,
+ const unsigned char *data, size_t mlen)
{
const char *error = NULL;
size_t keydata_len = 0;
uint16_t len;
int ec, i = 0;
- const unsigned char *digest_pos = NULL, *key_digest_pos = NULL, *key_ct_pos = NULL;
-
+ const unsigned char *digest_pos = NULL, *key_digest_pos = NULL,
+ *key_ct_pos = NULL;
size_t pos = sizeof(IOSTREAM_CRYPT_MAGIC);
- size_t digest_len = 0;
- size_t key_ct_len = 0;
- size_t key_digest_size = 0;
+ size_t digest_len = 0, key_ct_len = 0, key_digest_size = 0;
buffer_t ephemeral_key;
buffer_t *secret = t_buffer_create(256);
switch(i++) {
case 0:
- buffer_create_from_const_data(&ephemeral_key, data, len);
+ buffer_create_from_const_data(&ephemeral_key,
+ data, len);
break;
case 1:
/* public key id */
}
if (i < 4) {
- io_stream_set_error(&stream->istream.iostream, "Invalid or corrupted header");
+ io_stream_set_error(&stream->istream.iostream,
+ "Invalid or corrupted header");
/* was it consumed? */
stream->istream.istream.stream_errno =
mlen > 2 ? EINVAL : EPIPE;
if (stream->priv_key == NULL) {
/* see if we can get one */
if (stream->key_callback != NULL) {
- const char *key_id = binary_to_hex(digest_pos, digest_len);
- int ret = stream->key_callback(key_id, &stream->priv_key, &error, stream->key_context);
+ const char *key_id =
+ binary_to_hex(digest_pos, digest_len);
+ int ret = stream->key_callback(key_id,
+ &stream->priv_key, &error, stream->key_context);
if (ret < 0) {
- io_stream_set_error(&stream->istream.iostream, "Private key not available: %s", error);
+ io_stream_set_error(&stream->istream.iostream,
+ "Private key not available: %s",
+ error);
return -1;
}
if (ret == 0) {
- io_stream_set_error(&stream->istream.iostream, "Private key not available");
+ io_stream_set_error(&stream->istream.iostream,
+ "Private key not available");
return -1;
}
dcrypt_key_ref_private(stream->priv_key);
} else {
- io_stream_set_error(&stream->istream.iostream, "Private key not available");
+ io_stream_set_error(&stream->istream.iostream,
+ "Private key not available");
return -1;
}
}
buffer_t *check = t_buffer_create(32);
if (!dcrypt_key_id_private_old(stream->priv_key, check, &error)) {
- io_stream_set_error(&stream->istream.iostream, "Cannot get public key hash: %s", error);
+ io_stream_set_error(&stream->istream.iostream,
+ "Cannot get public key hash: %s", error);
return -1;
} else {
- if (memcmp(digest_pos, check->data, I_MIN(digest_len,check->used)) != 0) {
- io_stream_set_error(&stream->istream.iostream, "Private key not available");
+ if (memcmp(digest_pos, check->data,
+ I_MIN(digest_len,check->used)) != 0) {
+ io_stream_set_error(&stream->istream.iostream,
+ "Private key not available");
return -1;
}
}
/* derive shared secret */
- if (!dcrypt_ecdh_derive_secret_local(stream->priv_key, &ephemeral_key, secret, &error)) {
- io_stream_set_error(&stream->istream.iostream, "Cannot perform ECDH: %s", error);
+ if (!dcrypt_ecdh_derive_secret_local(stream->priv_key,
+ &ephemeral_key, secret, &error)) {
+ io_stream_set_error(&stream->istream.iostream,
+ "Cannot perform ECDH: %s", error);
return -1;
}
hash->result(hctx, hres);
safe_memset(buffer_get_modifiable_data(secret, 0), 0, secret->used);
- /* NB! The old code was broken and used this kind of IV - it is not correct, but
- we need to stay compatible with old data */
+ /* NB! The old code was broken and used this kind of IV - it is not
+ correct, but we need to stay compatible with old data */
/* use it to decrypt the actual encryption key */
struct dcrypt_context_symmetric *dctx;
- if (!dcrypt_ctx_sym_create("aes-256-ctr", DCRYPT_MODE_DECRYPT, &dctx, &error)) {
- io_stream_set_error(&stream->istream.iostream, "Key decryption error: %s", error);
+ if (!dcrypt_ctx_sym_create("aes-256-ctr", DCRYPT_MODE_DECRYPT,
+ &dctx, &error)) {
+ io_stream_set_error(&stream->istream.iostream,
+ "Key decryption error: %s", error);
return -1;
}
ec = 0;
- dcrypt_ctx_sym_set_iv(dctx, (const unsigned char*)"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16);
+ dcrypt_ctx_sym_set_iv(dctx, (const unsigned char*)
+ "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16);
dcrypt_ctx_sym_set_key(dctx, hres, hash->digest_size);
if (!dcrypt_ctx_sym_init(dctx, &error) ||
!dcrypt_ctx_sym_update(dctx, key_ct_pos, key_ct_len, key, &error) ||
!dcrypt_ctx_sym_final(dctx, key, &error)) {
- io_stream_set_error(&stream->istream.iostream, "Key decryption error: %s", error);
+ io_stream_set_error(&stream->istream.iostream,
+ "Key decryption error: %s", error);
ec = -1;
}
dcrypt_ctx_sym_destroy(&dctx);
if (ec != 0) {
- io_stream_set_error(&stream->istream.iostream, "Key decryption error: %s", error);
+ io_stream_set_error(&stream->istream.iostream,
+ "Key decryption error: %s", error);
return -1;
}
hash->result(hctx, hres);
if (key_digest_size != sizeof(hres)) {
- io_stream_set_error(&stream->istream.iostream, "Key decryption error: invalid digest length");
+ io_stream_set_error(&stream->istream.iostream,
+ "Key decryption error: "
+ "invalid digest length");
return -1;
}
if (memcmp(hres, key_digest_pos, sizeof(hres)) != 0) {
- io_stream_set_error(&stream->istream.iostream, "Key decryption error: decrypted key is invalid");
+ io_stream_set_error(&stream->istream.iostream,
+ "Key decryption error: "
+ "decrypted key is invalid");
return -1;
}
/* prime context with key */
- if (!dcrypt_ctx_sym_create("aes-256-ctr", DCRYPT_MODE_DECRYPT, &stream->ctx_sym, &error)) {
- io_stream_set_error(&stream->istream.iostream, "Decryption context create error: %s", error);
+ if (!dcrypt_ctx_sym_create("aes-256-ctr", DCRYPT_MODE_DECRYPT,
+ &stream->ctx_sym, &error)) {
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption context create error: %s",
+ error);
return -1;
}
/* Again, old code used this IV, so we have to use it too */
- dcrypt_ctx_sym_set_iv(stream->ctx_sym, (const unsigned char*)"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16);
+ dcrypt_ctx_sym_set_iv(stream->ctx_sym, (const unsigned char*)
+ "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16);
dcrypt_ctx_sym_set_key(stream->ctx_sym, key->data, key->used);
safe_memset(buffer_get_modifiable_data(key, 0), 0, key->used);
if (!dcrypt_ctx_sym_init(stream->ctx_sym, &error)) {
- io_stream_set_error(&stream->istream.iostream, "Decryption init error: %s", error);
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption init error: %s", error);
return -1;
}
return sizeof(IOSTREAM_CRYPT_MAGIC) + 1 + 2 + keydata_len;
}
-static bool get_msb32(const unsigned char **_data, const unsigned char *end, uint32_t *num_r)
+static bool
+get_msb32(const unsigned char **_data, const unsigned char *end,
+ uint32_t *num_r)
{
const unsigned char *data = *_data;
if (end-data < 4)
return TRUE;
}
-static
-bool i_stream_decrypt_der(const unsigned char **_data,
- const unsigned char *end, const char **str_r)
+static bool
+i_stream_decrypt_der(const unsigned char **_data, const unsigned char *end,
+ const char **str_r)
{
const unsigned char *data = *_data;
unsigned int len;
return TRUE;
}
-static
-ssize_t i_stream_decrypt_key(struct decrypt_istream *stream, const char *malg, unsigned int rounds,
- const unsigned char *data, const unsigned char *end, buffer_t *key, size_t key_len)
+static ssize_t
+i_stream_decrypt_key(struct decrypt_istream *stream, const char *malg,
+ unsigned int rounds, const unsigned char *data,
+ const unsigned char *end, buffer_t *key, size_t key_len)
{
const char *error;
enum dcrypt_key_type ktype;
/* if we have a key, prefab the digest */
if (stream->key_callback == NULL) {
if (stream->priv_key == NULL) {
- io_stream_set_error(&stream->istream.iostream, "Decryption error: no private key available");
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption error: "
+ "no private key available");
return -1;
}
buffer_create_from_data(&buf, dgst, sizeof(dgst));
if (!dcrypt_key_id_private(stream->priv_key, "sha256", &buf,
&error)) {
- io_stream_set_error(&stream->istream.iostream, "Decryption error: "
- "dcrypt_key_id_private failed: %s",
- error);
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption error: "
+ "dcrypt_key_id_private failed: %s",
+ error);
return -1;
}
}
ktype = *data++;
if (stream->key_callback != NULL) {
- const char *hexdgst = binary_to_hex(data, sizeof(dgst)); /* digest length */
+ const char *hexdgst = /* digest length */
+ binary_to_hex(data, sizeof(dgst));
/* hope you going to give us right key.. */
- int ret = stream->key_callback(hexdgst, &stream->priv_key, &error, stream->key_context);
+ int ret = stream->key_callback(hexdgst,
+ &stream->priv_key, &error, stream->key_context);
if (ret < 0) {
- io_stream_set_error(&stream->istream.iostream, "Private key not available: %s", error);
+ io_stream_set_error(&stream->istream.iostream,
+ "Private key not available: "
+ "%s", error);
return -1;
}
if (ret > 0) {
/* didn't find matching key */
if (!have_key) {
- io_stream_set_error(&stream->istream.iostream, "Decryption error: no private key available");
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption error: "
+ "no private key available");
return -1;
}
uint32_t ekhash_len;
/* read ephemeral key (can be missing for RSA) */
- if (!get_msb32(&data, end, &ep_key_len) || (size_t)(end-data) < ep_key_len)
+ if (!get_msb32(&data, end, &ep_key_len) ||
+ (size_t)(end-data) < ep_key_len)
return 0;
ephemeral_key = data;
data += ep_key_len;
data += eklen;
/* read key data hash */
- if (!get_msb32(&data, end, &ekhash_len) || (size_t)(end-data) < ekhash_len)
+ if (!get_msb32(&data, end, &ekhash_len) ||
+ (size_t)(end-data) < ekhash_len)
return 0;
ekhash = data;
data += ekhash_len;
/* decrypt the seed */
if (ktype == DCRYPT_KEY_RSA) {
- if (!dcrypt_rsa_decrypt(stream->priv_key, encrypted_key, eklen, key, &error)) {
- io_stream_set_error(&stream->istream.iostream, "key decryption error: %s", error);
+ if (!dcrypt_rsa_decrypt(stream->priv_key, encrypted_key,
+ eklen, key, &error)) {
+ io_stream_set_error(&stream->istream.iostream,
+ "key decryption error: %s", error);
return -1;
}
} else if (ktype == DCRYPT_KEY_EC) {
buffer_t *temp_key = t_buffer_create(256);
buffer_t *secret = t_buffer_create(256);
buffer_t peer_key;
- buffer_create_from_const_data(&peer_key, ephemeral_key, ep_key_len);
- if (!dcrypt_ecdh_derive_secret_local(stream->priv_key, &peer_key, secret, &error)) {
- io_stream_set_error(&stream->istream.iostream, "Key decryption error: corrupted header");
+ buffer_create_from_const_data(&peer_key,
+ ephemeral_key, ep_key_len);
+ if (!dcrypt_ecdh_derive_secret_local(stream->priv_key,
+ &peer_key, secret, &error)) {
+ io_stream_set_error(&stream->istream.iostream,
+ "Key decryption error: corrupted header");
return -1;
}
- /* use shared secret and peer key to generate decryption key, AES-256-CBC has 32 byte key and 16 byte IV */
- if (!dcrypt_pbkdf2(secret->data, secret->used, peer_key.data, peer_key.used,
- malg, rounds, temp_key, 32+16, &error)) {
- safe_memset(buffer_get_modifiable_data(secret, 0), 0, secret->used);
- io_stream_set_error(&stream->istream.iostream, "Key decryption error: %s", error);
+ /* use shared secret and peer key to generate decryption key,
+ AES-256-CBC has 32 byte key and 16 byte IV */
+ if (!dcrypt_pbkdf2(secret->data, secret->used,
+ peer_key.data, peer_key.used,
+ malg, rounds, temp_key, 32+16, &error)) {
+ safe_memset(buffer_get_modifiable_data(secret, 0),
+ 0, secret->used);
+ io_stream_set_error(&stream->istream.iostream,
+ "Key decryption error: %s", error);
return -1;
}
- safe_memset(buffer_get_modifiable_data(secret, 0), 0, secret->used);
+ safe_memset(buffer_get_modifiable_data(secret, 0),
+ 0, secret->used);
if (temp_key->used != 32+16) {
- safe_memset(buffer_get_modifiable_data(temp_key, 0), 0, temp_key->used);
- io_stream_set_error(&stream->istream.iostream, "Cannot perform key decryption: invalid temporary key");
+ safe_memset(buffer_get_modifiable_data(temp_key, 0),
+ 0, temp_key->used);
+ io_stream_set_error(&stream->istream.iostream,
+ "Cannot perform key decryption: "
+ "invalid temporary key");
return -1;
}
struct dcrypt_context_symmetric *dctx;
- if (!dcrypt_ctx_sym_create("AES-256-CBC", DCRYPT_MODE_DECRYPT, &dctx, &error)) {
- safe_memset(buffer_get_modifiable_data(temp_key, 0), 0, temp_key->used);
- io_stream_set_error(&stream->istream.iostream, "Key decryption error: %s", error);
+ if (!dcrypt_ctx_sym_create("AES-256-CBC", DCRYPT_MODE_DECRYPT,
+ &dctx, &error)) {
+ safe_memset(buffer_get_modifiable_data(temp_key, 0),
+ 0, temp_key->used);
+ io_stream_set_error(&stream->istream.iostream,
+ "Key decryption error: %s", error);
return -1;
}
const unsigned char *ptr = temp_key->data;
/* we use ephemeral_key for IV */
dcrypt_ctx_sym_set_key(dctx, ptr, 32);
dcrypt_ctx_sym_set_iv(dctx, ptr+32, 16);
- safe_memset(buffer_get_modifiable_data(temp_key, 0), 0, temp_key->used);
+ safe_memset(buffer_get_modifiable_data(temp_key, 0),
+ 0, temp_key->used);
int ec = 0;
if (!dcrypt_ctx_sym_init(dctx, &error) ||
- !dcrypt_ctx_sym_update(dctx, encrypted_key, eklen, key, &error) ||
+ !dcrypt_ctx_sym_update(dctx, encrypted_key, eklen,
+ key, &error) ||
!dcrypt_ctx_sym_final(dctx, key, &error)) {
- io_stream_set_error(&stream->istream.iostream, "Cannot perform key decryption: %s", error);
+ io_stream_set_error(&stream->istream.iostream,
+ "Cannot perform key decryption: %s",
+ error);
ec = -1;
}
if (key->used != key_len) {
- io_stream_set_error(&stream->istream.iostream, "Cannot perform key decryption: invalid key length");
+ io_stream_set_error(&stream->istream.iostream,
+ "Cannot perform key decryption: "
+ "invalid key length");
ec = -1;
}
dcrypt_ctx_sym_destroy(&dctx);
if (ec != 0) return ec;
} else {
- io_stream_set_error(&stream->istream.iostream, "Decryption error: unsupported key type 0x%02x", ktype);
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption error: "
+ "unsupported key type 0x%02x", ktype);
return -1;
}
const struct hash_method *hash = hash_method_lookup(t_str_lcase(malg));
if (hash == NULL) {
safe_memset(buffer_get_modifiable_data(key, 0), 0, key->used);
- io_stream_set_error(&stream->istream.iostream, "Decryption error: unsupported hash algorithm: %s", malg);
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption error: "
+ "unsupported hash algorithm: %s", malg);
return -1;
}
unsigned char hctx[hash->context_size];
/* do the comparison */
if (memcmp(ekhash, hres, I_MIN(ekhash_len, sizeof(hres))) != 0) {
safe_memset(buffer_get_modifiable_data(key, 0), 0, key->used);
- io_stream_set_error(&stream->istream.iostream, "Decryption error: corrupted header ekhash");
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption error: "
+ "corrupted header ekhash");
return -1;
}
return 1;
}
-static
-int i_stream_decrypt_header_contents(struct decrypt_istream *stream,
- const unsigned char *data, size_t size)
+static int
+i_stream_decrypt_header_contents(struct decrypt_istream *stream,
+ const unsigned char *data, size_t size)
{
const unsigned char *end = data + size;
bool failed = FALSE;
const char *calg;
if (!i_stream_decrypt_der(&data, end, &calg))
return 0;
- if (calg == NULL || !dcrypt_ctx_sym_create(calg, DCRYPT_MODE_DECRYPT, &stream->ctx_sym, NULL)) {
- io_stream_set_error(&stream->istream.iostream, "Decryption error: unsupported/invalid cipher: %s", calg);
+ if (calg == NULL ||
+ !dcrypt_ctx_sym_create(calg, DCRYPT_MODE_DECRYPT,
+ &stream->ctx_sym, NULL)) {
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption error: "
+ "unsupported/invalid cipher: %s", calg);
return -1;
}
if (!i_stream_decrypt_der(&data, end, &malg))
return 0;
if (malg == NULL || !dcrypt_ctx_hmac_create(malg, &stream->ctx_mac, NULL)) {
- io_stream_set_error(&stream->istream.iostream, "Decryption error: unsupported/invalid MAC algorithm: %s", malg);
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption error: "
+ "unsupported/invalid MAC algorithm: %s",
+ malg);
return -1;
}
size_t tagsize;
- if ((stream->flags & IO_STREAM_ENC_INTEGRITY_HMAC) == IO_STREAM_ENC_INTEGRITY_HMAC) {
+ if ((stream->flags & IO_STREAM_ENC_INTEGRITY_HMAC) ==
+ IO_STREAM_ENC_INTEGRITY_HMAC) {
tagsize = IOSTREAM_TAG_SIZE;
- } else if ((stream->flags & IO_STREAM_ENC_INTEGRITY_AEAD) == IO_STREAM_ENC_INTEGRITY_AEAD) {
+ } else if ((stream->flags & IO_STREAM_ENC_INTEGRITY_AEAD) ==
+ IO_STREAM_ENC_INTEGRITY_AEAD) {
tagsize = IOSTREAM_TAG_SIZE;
} else {
tagsize = 0;
}
/* how much key data we should be getting */
- size_t kl = dcrypt_ctx_sym_get_key_length(stream->ctx_sym) + dcrypt_ctx_sym_get_iv_length(stream->ctx_sym) + tagsize;
+ size_t kl = dcrypt_ctx_sym_get_key_length(stream->ctx_sym) +
+ dcrypt_ctx_sym_get_iv_length(stream->ctx_sym) + tagsize;
buffer_t *keydata = t_buffer_create(kl);
/* try to decrypt the keydata with a private key */
int ret;
- if ((ret = i_stream_decrypt_key(stream, malg, rounds, data, end, keydata, kl)) <= 0)
+ if ((ret = i_stream_decrypt_key(stream, malg, rounds, data,
+ end, keydata, kl)) <= 0)
return ret;
/* oh, it worked! */
const unsigned char *ptr = keydata->data;
if (keydata->used != kl) {
/* but returned wrong amount of data */
- io_stream_set_error(&stream->istream.iostream, "Key decryption error: Key data length mismatch");
+ io_stream_set_error(&stream->istream.iostream,
+ "Key decryption error: "
+ "Key data length mismatch");
return -1;
}
/* prime contexts */
- dcrypt_ctx_sym_set_key(stream->ctx_sym, ptr, dcrypt_ctx_sym_get_key_length(stream->ctx_sym));
+ dcrypt_ctx_sym_set_key(stream->ctx_sym, ptr,
+ dcrypt_ctx_sym_get_key_length(stream->ctx_sym));
ptr += dcrypt_ctx_sym_get_key_length(stream->ctx_sym);
- dcrypt_ctx_sym_set_iv(stream->ctx_sym, ptr, dcrypt_ctx_sym_get_iv_length(stream->ctx_sym));
+ dcrypt_ctx_sym_set_iv(stream->ctx_sym, ptr,
+ dcrypt_ctx_sym_get_iv_length(stream->ctx_sym));
stream->iv = i_malloc(dcrypt_ctx_sym_get_iv_length(stream->ctx_sym));
memcpy(stream->iv, ptr, dcrypt_ctx_sym_get_iv_length(stream->ctx_sym));
ptr += dcrypt_ctx_sym_get_iv_length(stream->ctx_sym);
/* based on the chosen MAC, initialize HMAC or AEAD */
- if ((stream->flags & IO_STREAM_ENC_INTEGRITY_HMAC) == IO_STREAM_ENC_INTEGRITY_HMAC) {
+ if ((stream->flags & IO_STREAM_ENC_INTEGRITY_HMAC) ==
+ IO_STREAM_ENC_INTEGRITY_HMAC) {
const char *error;
dcrypt_ctx_hmac_set_key(stream->ctx_mac, ptr, tagsize);
if (!dcrypt_ctx_hmac_init(stream->ctx_mac, &error)) {
- io_stream_set_error(&stream->istream.iostream, "MAC error: %s", error);
+ io_stream_set_error(&stream->istream.iostream,
+ "MAC error: %s", error);
stream->istream.istream.stream_errno = EINVAL;
failed = TRUE;
}
stream->ftr = dcrypt_ctx_hmac_get_digest_length(stream->ctx_mac);
stream->use_mac = TRUE;
- } else if ((stream->flags & IO_STREAM_ENC_INTEGRITY_AEAD) == IO_STREAM_ENC_INTEGRITY_AEAD) {
+ } else if ((stream->flags & IO_STREAM_ENC_INTEGRITY_AEAD) ==
+ IO_STREAM_ENC_INTEGRITY_AEAD) {
dcrypt_ctx_sym_set_aad(stream->ctx_sym, ptr, tagsize);
stream->ftr = tagsize;
stream->use_mac = TRUE;
return failed ? -1 : 1;
}
-static
-ssize_t i_stream_decrypt_read_header(struct decrypt_istream *stream,
- const unsigned char *data, size_t mlen)
+static ssize_t
+i_stream_decrypt_read_header(struct decrypt_istream *stream,
+ const unsigned char *data, size_t mlen)
{
const char *error;
const unsigned char *end = data + mlen;
if (mlen < sizeof(IOSTREAM_CRYPT_MAGIC))
return 0;
if (memcmp(data, IOSTREAM_CRYPT_MAGIC, sizeof(IOSTREAM_CRYPT_MAGIC)) != 0) {
- io_stream_set_error(&stream->istream.iostream, "Stream is not encrypted (invalid magic)");
+ io_stream_set_error(&stream->istream.iostream,
+ "Stream is not encrypted (invalid magic)");
stream->istream.istream.stream_errno = EINVAL;
return -1;
}
/* check version */
if (*data == '\x01') {
stream->format = DECRYPT_FORMAT_V1;
- return i_stream_decrypt_read_header_v1(stream, data+1, end - (data+1));
+ return i_stream_decrypt_read_header_v1(stream, data+1,
+ end - (data+1));
} else if (*data != '\x02') {
- io_stream_set_error(&stream->istream.iostream, "Unsupported encrypted data 0x%02x", *data);
+ io_stream_set_error(&stream->istream.iostream,
+ "Unsupported encrypted data 0x%02x", *data);
return -1;
}
if ((ret = i_stream_decrypt_header_contents(stream, data, hdr_len)) < 0)
return -1;
else if (ret == 0) {
- io_stream_set_error(&stream->istream.iostream, "Decryption error: truncate header length");
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption error: truncate header length");
stream->istream.istream.stream_errno = EPIPE;
return -1;
}
/* if it all went well, try to initialize decryption context */
if (!dcrypt_ctx_sym_init(stream->ctx_sym, &error)) {
- io_stream_set_error(&stream->istream.iostream, "Decryption init error: %s", error);
+ io_stream_set_error(&stream->istream.iostream,
+ "Decryption init error: %s", error);
return -1;
}
return hdr_len;
if (dstream->initialized && dstream->buf->used > 0) {
size_t new_pos, bytes;
- /* only return up to max_buffer_size bytes, even when buffer
- actually has more, as not to confuse the caller */
- if (dstream->buf->used <= dstream->istream.max_buffer_size) {
+ /* only return up to max_buffer_size bytes, even when
+ buffer actually has more, as not to confuse the
+ caller */
+ if (dstream->buf->used <=
+ dstream->istream.max_buffer_size) {
new_pos = dstream->buf->used;
if (dstream->finalized)
stream->istream.eof = TRUE;
data = i_stream_get_data(stream->parent, &size);
- if (ret == -1 && (size == 0 || stream->parent->stream_errno != 0)) {
- stream->istream.stream_errno = stream->parent->stream_errno;
+ if (ret == -1 &&
+ (size == 0 || stream->parent->stream_errno != 0)) {
+ stream->istream.stream_errno =
+ stream->parent->stream_errno;
/* file was empty */
- if (!dstream->initialized && size == 0 && stream->parent->eof) {
+ if (!dstream->initialized &&
+ size == 0 && stream->parent->eof) {
stream->istream.eof = TRUE;
return -1;
}
if (!dstream->initialized) {
ssize_t hret;
- if ((hret=i_stream_decrypt_read_header(dstream, data, size)) <= 0) {
+ if ((hret=i_stream_decrypt_read_header(
+ dstream, data, size)) <= 0) {
if (hret < 0) {
if (stream->istream.stream_errno == 0)
/* assume temporary failure */
if (ret == -2) {
stream->istream.stream_errno = EINVAL;
io_stream_set_error(&stream->iostream,
- "Header too large (more than %"PRIuSIZE_T" bytes)", size);
+ "Header too large "
+ "(more than %"PRIuSIZE_T" bytes)",
+ size);
return -1;
}
continue;
} else {
/* clean up buffer */
- safe_memset(buffer_get_modifiable_data(dstream->buf, 0), 0, dstream->buf->used);
+ safe_memset(buffer_get_modifiable_data(dstream->buf, 0),
+ 0, dstream->buf->used);
buffer_set_used_size(dstream->buf, 0);
i_stream_skip(stream->parent, hret);
}
if (stream->parent->eof) {
if (decrypt_size < dstream->ftr) {
io_stream_set_error(&stream->iostream,
- "Decryption error: footer is longer than data");
+ "Decryption error: "
+ "footer is longer than data");
stream->istream.stream_errno = EINVAL;
return -1;
}
size -= dstream->ftr;
}
decrypt_size -= dstream->ftr;
- if ((dstream->flags & IO_STREAM_ENC_INTEGRITY_HMAC) == IO_STREAM_ENC_INTEGRITY_HMAC) {
+ if ((dstream->flags & IO_STREAM_ENC_INTEGRITY_HMAC) ==
+ IO_STREAM_ENC_INTEGRITY_HMAC) {
if (!dcrypt_ctx_hmac_update(dstream->ctx_mac,
data, decrypt_size, &error)) {
io_stream_set_error(&stream->iostream,
}
if (check_mac) {
- if ((dstream->flags & IO_STREAM_ENC_INTEGRITY_HMAC) == IO_STREAM_ENC_INTEGRITY_HMAC) {
+ if ((dstream->flags & IO_STREAM_ENC_INTEGRITY_HMAC) ==
+ IO_STREAM_ENC_INTEGRITY_HMAC) {
unsigned char dgst[dcrypt_ctx_hmac_get_digest_length(dstream->ctx_mac)];
buffer_t db;
buffer_create_from_data(&db, dgst, sizeof(dgst));
stream->istream.stream_errno = EINVAL;
return -1;
}
- if (memcmp(dgst, data + decrypt_size, dcrypt_ctx_hmac_get_digest_length(dstream->ctx_mac)) != 0) {
+ if (memcmp(dgst, data + decrypt_size,
+ dcrypt_ctx_hmac_get_digest_length(dstream->ctx_mac)) != 0) {
io_stream_set_error(&stream->iostream,
"Cannot verify MAC: mismatch");
stream->istream.stream_errno = EINVAL;
return -1;
}
- } else if ((dstream->flags & IO_STREAM_ENC_INTEGRITY_AEAD) == IO_STREAM_ENC_INTEGRITY_AEAD) {
- dcrypt_ctx_sym_set_tag(dstream->ctx_sym, data + decrypt_size, dstream->ftr);
+ } else if ((dstream->flags & IO_STREAM_ENC_INTEGRITY_AEAD) ==
+ IO_STREAM_ENC_INTEGRITY_AEAD) {
+ dcrypt_ctx_sym_set_tag(dstream->ctx_sym,
+ data + decrypt_size,
+ dstream->ftr);
}
}
}
}
-static
-void i_stream_decrypt_close(struct iostream_private *stream,
+static void i_stream_decrypt_close(struct iostream_private *stream,
bool close_parent)
{
struct decrypt_istream *dstream =
i_stream_close(dstream->istream.parent);
}
-static
-void i_stream_decrypt_destroy(struct iostream_private *stream)
+static void i_stream_decrypt_destroy(struct iostream_private *stream)
{
struct decrypt_istream *dstream =
(struct decrypt_istream *)stream;
i_stream_unref(&dstream->istream.parent);
}
-static
-struct decrypt_istream *i_stream_create_decrypt_common(struct istream *input)
+static struct decrypt_istream *
+i_stream_create_decrypt_common(struct istream *input)
{
struct decrypt_istream *dstream;
}
struct istream *
-i_stream_create_decrypt(struct istream *input, struct dcrypt_private_key *priv_key)
+i_stream_create_decrypt(struct istream *input,
+ struct dcrypt_private_key *priv_key)
{
struct decrypt_istream *dstream;
}
struct istream *
-i_stream_create_sym_decrypt(struct istream *input, struct dcrypt_context_symmetric *ctx)
+i_stream_create_sym_decrypt(struct istream *input,
+ struct dcrypt_context_symmetric *ctx)
{
const char *error;
int ec;
dstream->ctx_sym = ctx;
if (ec != 0) {
- io_stream_set_error(&dstream->istream.iostream, "Cannot initialize decryption: %s", error);
+ io_stream_set_error(&dstream->istream.iostream,
+ "Cannot initialize decryption: %s", error);
dstream->istream.istream.stream_errno = EIO;
};