char *cipher_aes_decrypt_base64(const char *ciphertext, const unsigned char key[KDF_HASH_LEN]) { _cleanup_free_ char *copy = NULL; _cleanup_free_ char *iv = NULL; _cleanup_free_ char *data = NULL; _cleanup_free_ char *unbase64_ciphertext = NULL; char *pipe; size_t iv_len, data_len, len; if (!strlen(ciphertext)) return NULL; if (ciphertext[0] == '!') { copy = xstrdup(&ciphertext[1]); pipe = strchr(copy, '|'); if (!pipe) return NULL; *pipe = '\0'; iv_len = unbase64(copy, &iv); data_len = unbase64(pipe + 1, &data); len = iv_len + data_len + 1 /* pound */; unbase64_ciphertext = xcalloc(len, 1); unbase64_ciphertext[0] = '!'; memcpy(&unbase64_ciphertext[1], iv, iv_len); memcpy(&unbase64_ciphertext[1 + iv_len], data, data_len); return cipher_aes_decrypt(unbase64_ciphertext, len, key); } else { len = unbase64(ciphertext, &data); return cipher_aes_decrypt(data, len, key); } }
static char *read_crypt_string(struct chunk *chunk, const unsigned char key[KDF_HASH_LEN], char **stored_base64) { struct item item; char *ptext; if (!read_item(chunk, &item)) return NULL; if (stored_base64) *stored_base64 = cipher_base64(item.data, item.len); if (item.len == 0) return xstrdup(""); ptext = cipher_aes_decrypt(item.data, item.len, key); if (!ptext) /* don't fail whole blob if this item cannot be decrypted */ return xstrdup(""); return ptext; }