opvault.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 09 Apr 2020 02:15:46 -0400
changeset 60 a0629a9e3ee6
parent 58 1390348facc7
permissions -rw-r--r--
otp: Some base32-decoding fixes to match what Google Authenticator expects.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
58
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     1
// https://support.1password.com/opvault-design
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     2
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     3
#include <stdio.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     4
#include <stdlib.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     5
#include <string.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     6
#include <stdint.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     7
#include <unistd.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     8
#include <time.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     9
#include <errno.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    10
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    11
#include <openssl/bio.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    12
#include <openssl/evp.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    13
#include <openssl/hmac.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    14
#include <openssl/err.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    15
#include <openssl/conf.h>
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    16
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    17
#include "cJSON.h"
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    18
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    19
#define JSONVAR(typ, var, jstyp, json, name) typ var; { \
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    20
    cJSON *item = cJSON_GetObjectItem(json, name); \
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    21
    if (!item) { \
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    22
        fprintf(stderr, "No " name " field in profile.\n"); \
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    23
        return 0; \
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    24
    } \
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    25
    var = (typ) item->value##jstyp; \
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    26
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    27
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    28
static cJSON *load_json(const char *fname)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    29
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    30
    cJSON *retval = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    31
    FILE *io = fopen(fname, "rb");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    32
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    33
    if (io != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    34
        if (fseek(io, 0, SEEK_END) == 0) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    35
            long len = ftell(io);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    36
            if ((len != -1) && (fseek(io, 0, SEEK_SET) == 0)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    37
                char *buf = (char *) malloc(len + 1);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    38
                if ((buf != NULL) && (fread(buf, len, 1, io) == 1)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    39
                    char *json = buf;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    40
                    json[len] = '\0';
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    41
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    42
                    // !!! FIXME: hack.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    43
                    if (strncmp(json, "ld(", 3) == 0) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    44
                        json[len-2] = '\0';  // chop off ");" from end.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    45
                        json += 3;  // skip past "ld(".
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    46
                        len -= 5;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    47
                    } else if (strncmp(json, "loadFolders(", 12) == 0) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    48
                        json[len-2] = '\0';  // chop off ");" from end.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    49
                        json += 12;  // skip past "loadFolders(".
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    50
                        len -= 14;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    51
                    } else if (strncmp(json, "var profile=", 12) == 0) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    52
                        json[len-1] = '\0';  // chop off ";" from end.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    53
                        json += 12;  // skip past "var profile=".
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    54
                        len -= 13;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    55
                    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    56
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    57
                    retval = cJSON_Parse(json);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    58
                }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    59
                free(buf);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    60
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    61
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    62
        fclose(io);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    63
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    64
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    65
    return retval;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    66
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    67
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    68
static void dump_json_internal(const cJSON *json, const int indent)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    69
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    70
    const cJSON *i;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    71
    int j;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    72
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    73
    if (!json) return;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    74
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    75
    for (j = 0; j < (indent*2); j++) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    76
        printf(" ");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    77
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    78
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    79
    if (json->string != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    80
        printf("%s : ", json->string);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    81
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    82
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    83
    switch (json->type) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    84
        default: printf("[!unknown type!]"); break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    85
        case cJSON_Invalid: printf("[!invalid!]"); break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    86
        case cJSON_False: printf("false"); break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    87
        case cJSON_True: printf("true"); break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    88
        case cJSON_NULL: printf("null"); break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    89
        case cJSON_Number: printf("%f", json->valuedouble); break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    90
        case cJSON_Raw: printf("!CDATA[\"%s\"]", json->valuestring); break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    91
        case cJSON_String: printf("\"%s\"", json->valuestring); break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    92
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    93
        case cJSON_Array:
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    94
            printf("[\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    95
            for (i = json->child; i != NULL; i = i->next) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    96
                dump_json_internal(i, indent + 1);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    97
                if (i->next != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    98
                    printf(", ");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    99
                }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   100
                printf("\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   101
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   102
            for (j = 0; j < (indent*2); j++) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   103
                printf(" ");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   104
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   105
            printf("]");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   106
            break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   107
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   108
        case cJSON_Object:
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   109
            printf("{\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   110
            for (i = json->child; i != NULL; i = i->next) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   111
                dump_json_internal(i, indent + 1);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   112
                if (i->next != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   113
                    printf(", ");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   114
                }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   115
                printf("\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   116
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   117
            for (j = 0; j < (indent*2); j++) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   118
                printf(" ");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   119
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   120
            printf("}");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   121
            break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   122
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   123
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   124
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   125
static void dump_json(const cJSON *json)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   126
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   127
    dump_json_internal(json, 0);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   128
    printf("\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   129
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   130
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   131
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   132
static int base64_decode(const char *in, const int inlen, uint8_t **out)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   133
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   134
    const int len = (inlen == -1) ? (int) strlen(in) : inlen;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   135
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   136
    *out = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   137
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   138
    BIO *b64f = BIO_new(BIO_f_base64());
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   139
    BIO *buff = buff = BIO_push(b64f, BIO_new_mem_buf(in, len));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   140
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   141
    uint8_t *decoded = (uint8_t *) malloc(len);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   142
    if (!decoded) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   143
        fprintf(stderr, "Out of memory!\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   144
        return -1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   145
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   146
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   147
    BIO_set_flags(buff, BIO_FLAGS_BASE64_NO_NL);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   148
    BIO_set_close(buff, BIO_CLOSE);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   149
    const int retval = BIO_read(buff, decoded, len);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   150
    if (retval < 0) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   151
        free(decoded);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   152
        return -1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   153
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   154
    decoded[retval] = '\0';
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   155
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   156
    BIO_free_all(buff);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   157
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   158
    *out = decoded;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   159
    return retval;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   160
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   161
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   162
static int decrypt_opdata(const char *name, const uint8_t *opdata, const int opdatalen, const uint8_t *encryptionkey, const uint8_t *mackey, uint8_t **out, int *outlen)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   163
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   164
    *out = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   165
    if (outlen) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   166
        *outlen = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   167
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   168
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   169
    if ((opdatalen < 64) || (memcmp(opdata, "opdata01", 8) != 0)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   170
        fprintf(stderr, "opdata(%s) isn't actually in opdata01 format.\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   171
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   172
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   173
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   174
    // !!! FIXME: byteswap
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   175
    const int plaintextlen = (int) (*((uint64_t *) (opdata + 8)));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   176
    const int paddedplaintextlen = plaintextlen + (16 - (plaintextlen % 16));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   177
    if (paddedplaintextlen > (opdatalen - (8 + 8 + 16 + 32))) {  // minus magic, len, iv, hmac
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   178
        fprintf(stderr, "opdata(%s) plaintext length is bogus.\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   179
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   180
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   181
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   182
    uint8_t digest[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   183
    unsigned int digestlen = sizeof (digest);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   184
    if (!HMAC(EVP_sha256(), mackey, 32, opdata, opdatalen-32, (unsigned char *) digest, &digestlen)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   185
        fprintf(stderr, "opdata(%s) HMAC failed.\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   186
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   187
    } else if (digestlen != sizeof (digest)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   188
        fprintf(stderr, "opdata(%s) HMAC is wrong size (got=%u expected=%u).\n", name, digestlen, (unsigned int) sizeof (digest));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   189
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   190
    } else if (memcmp(digest, opdata + (opdatalen-sizeof (digest)), sizeof (digest)) != 0) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   191
        fprintf(stderr, "opdata(%s) HMAC verification failed.\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   192
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   193
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   194
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   195
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   196
    if (!ctx) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   197
        fprintf(stderr, "opdata(%s) EVP_CIPHER_CTX_new() failed\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   198
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   199
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   200
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   201
    const unsigned char *iv = (unsigned char *) (opdata + 16);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   202
    if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char *) encryptionkey, iv)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   203
        fprintf(stderr, "opdata(%s) EVP_DecryptInit_ex() failed\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   204
        EVP_CIPHER_CTX_cleanup(ctx);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   205
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   206
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   207
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   208
    EVP_CIPHER_CTX_set_padding(ctx, 0);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   209
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   210
    uint8_t *plaintext = (uint8_t *) malloc(paddedplaintextlen);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   211
    if (!plaintext) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   212
        fprintf(stderr, "opdata(%s) Out of memory.\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   213
        EVP_CIPHER_CTX_cleanup(ctx);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   214
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   215
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   216
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   217
    // opdata+32 == first byte past magic, len, and iv.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   218
    int decryptedlen = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   219
    if (!EVP_DecryptUpdate(ctx, plaintext, &decryptedlen, opdata + 32, paddedplaintextlen)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   220
        fprintf(stderr, "opdata(%s) EVP_DecryptUpdate() failed\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   221
        free(plaintext);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   222
        EVP_CIPHER_CTX_cleanup(ctx);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   223
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   224
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   225
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   226
    int totaldecryptedlen = decryptedlen;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   227
    if (!EVP_DecryptFinal_ex(ctx, plaintext + decryptedlen, &decryptedlen)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   228
        fprintf(stderr, "opdata(%s) EVP_DecryptFinal_ex() failed\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   229
        free(plaintext);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   230
        EVP_CIPHER_CTX_cleanup(ctx);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   231
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   232
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   233
    totaldecryptedlen += decryptedlen;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   234
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   235
    EVP_CIPHER_CTX_cleanup(ctx);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   236
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   237
    if (totaldecryptedlen != paddedplaintextlen) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   238
        fprintf(stderr, "opdata(%s) decrypted to wrong size (got=%d expected=%u).\n", name, totaldecryptedlen, (unsigned int) paddedplaintextlen);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   239
        free(plaintext);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   240
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   241
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   242
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   243
    // random padding bytes are prepended. Drop them.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   244
    const int paddinglen = paddedplaintextlen - plaintextlen;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   245
    memmove(plaintext, plaintext + paddinglen, plaintextlen);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   246
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   247
    *out = plaintext;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   248
    if (outlen) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   249
        *outlen = plaintextlen;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   250
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   251
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   252
    return 1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   253
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   254
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   255
static int decrypt_opdata_base64(const char *name, const char *base64data, const uint8_t *encryptionkey, const uint8_t *mackey, uint8_t **out, int *outlen)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   256
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   257
    uint8_t *opdata = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   258
    const int opdatalen = base64_decode(base64data, -1, &opdata);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   259
    if (opdatalen == -1) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   260
        fprintf(stderr, "opdata(%s) wasn't a valid base64 string\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   261
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   262
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   263
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   264
    const int retval = decrypt_opdata(name, opdata, opdatalen, encryptionkey, mackey, out, outlen);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   265
    free(opdata);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   266
    return retval;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   267
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   268
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   269
static int decrypt_key(const char *name, const char *base64data, const uint8_t *encryptionkey, const uint8_t *mackey, uint8_t *finalkey, uint8_t *finalhmac)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   270
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   271
    uint8_t *decryptedkey = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   272
    int decryptedkeylen = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   273
    if (!decrypt_opdata_base64(name, base64data, encryptionkey, mackey, &decryptedkey, &decryptedkeylen)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   274
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   275
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   276
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   277
    uint8_t digest[64];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   278
    unsigned int digestlen = sizeof (digest);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   279
    const int rc = EVP_Digest(decryptedkey, decryptedkeylen, (unsigned char *) digest, &digestlen, EVP_sha512(), NULL);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   280
    free(decryptedkey);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   281
    if (!rc) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   282
        fprintf(stderr, "Hashing %s failed.\n", name);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   283
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   284
    } else if (digestlen != sizeof (digest)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   285
        fprintf(stderr, "Hash for %s is wrong size (got=%u expected=%u).\n", name, digestlen, (unsigned int) sizeof (digest));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   286
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   287
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   288
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   289
    memcpy(finalkey, digest, 32);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   290
    memcpy(finalhmac, digest + 32, 32);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   291
    return 1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   292
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   293
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   294
static int derive_keys_from_password(const char *password, const char *base64salt, const int iterations, uint8_t *encryptionkey, uint8_t *mackey)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   295
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   296
    uint8_t salt[16];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   297
    uint8_t *buf = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   298
    int saltlen = base64_decode(base64salt, -1, &buf);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   299
    if (saltlen == -1) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   300
        fprintf(stderr, "Salt wasn't a valid base64 string.\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   301
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   302
    } else if (saltlen != 16) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   303
        fprintf(stderr, "Expected salt to base64-decode to 16 bytes (it was %lu).\n", (unsigned long) saltlen);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   304
        free(buf);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   305
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   306
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   307
    memcpy(salt, buf, saltlen);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   308
    free(buf);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   309
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   310
    uint8_t derived[64];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   311
    if (!PKCS5_PBKDF2_HMAC(password, -1,
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   312
            (const unsigned char *) salt, saltlen, iterations,
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   313
            EVP_sha512(), sizeof (derived), (unsigned char *) derived)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   314
        fprintf(stderr, "Key derivation failed.\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   315
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   316
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   317
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   318
    // first half of the derived key is the encryption key, second half is MAC key.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   319
    memcpy(encryptionkey, derived, 32);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   320
    memcpy(mackey, derived + 32, 32);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   321
    return 1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   322
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   323
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   324
static int prepare_keys(cJSON *profile, const char *password,
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   325
                        uint8_t *masterkey, uint8_t *masterhmac,
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   326
                        uint8_t *overviewkey, uint8_t *overviewhmac)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   327
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   328
    JSONVAR(const char *, base64salt, string, profile, "salt");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   329
    JSONVAR(const char *, base64masterkey, string, profile, "masterKey");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   330
    JSONVAR(const char *, base64overviewkey, string, profile, "overviewKey");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   331
    JSONVAR(int, iterations, double, profile, "iterations");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   332
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   333
    uint8_t encryptionkey[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   334
    uint8_t mackey[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   335
    if (!derive_keys_from_password(password, base64salt, iterations, encryptionkey, mackey)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   336
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   337
    } else if (!decrypt_key("master key", base64masterkey, encryptionkey, mackey, masterkey, masterhmac)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   338
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   339
    } else if (!decrypt_key("overview key", base64overviewkey, encryptionkey, mackey, overviewkey, overviewhmac)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   340
        return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   341
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   342
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   343
    return 1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   344
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   345
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   346
static void dump_folders(const uint8_t *overviewkey, const uint8_t *overviewhmac)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   347
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   348
    cJSON *folders = load_json("folders.js");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   349
    cJSON *i;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   350
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   351
    if (!folders || !folders->child) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   352
        printf("(no folders.)\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   353
        return;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   354
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   355
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   356
    printf("\nFolders...\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   357
    for (i = folders->child; i != NULL; i = i->next) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   358
        char *encrypted = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   359
        uint8_t *decrypted = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   360
        cJSON *overview = cJSON_GetObjectItem(i, "overview");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   361
        if (overview) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   362
            encrypted = overview->valuestring;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   363
            int decryptedlen = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   364
            if (decrypt_opdata_base64("overview", encrypted, overviewkey, overviewhmac, &decrypted, &decryptedlen)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   365
                decrypted[decryptedlen] = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   366
                overview->valuestring = (char *) decrypted;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   367
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   368
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   369
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   370
        dump_json(i);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   371
        printf("\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   372
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   373
        if (overview) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   374
            overview->valuestring = encrypted; // put this back for cleanup.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   375
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   376
        free(decrypted);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   377
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   378
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   379
    printf("\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   380
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   381
    cJSON_Delete(folders);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   382
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   383
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   384
typedef struct CategoryMap
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   385
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   386
    const char *name;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   387
    const char *idstr;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   388
} CategoryMap;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   389
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   390
static const CategoryMap category_map[] = {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   391
    { "Login", "001" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   392
    { "Credit Card", "002" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   393
    { "Secure Note", "003" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   394
    { "Identity", "004" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   395
    { "Password", "005" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   396
    { "Tombstone", "099" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   397
    { "Software License", "100" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   398
    { "Bank Account", "101" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   399
    { "Database", "102" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   400
    { "Driver License", "103" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   401
    { "Outdoor License", "104" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   402
    { "Membership", "105" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   403
    { "Passport", "106" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   404
    { "Rewards", "107" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   405
    { "SSN", "108" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   406
    { "Router", "109" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   407
    { "Server", "110" },
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   408
    { "Email", "111" }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   409
};
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   410
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   411
static int compare_cjson_by_fieldname(const void *a, const void *b)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   412
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   413
    return strcmp( (*(const cJSON **) a)->string, (*(const cJSON **) b)->string );
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   414
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   415
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   416
static int test_item_hmac(cJSON *item, const char *base64hmac, const uint8_t *overviewhmac)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   417
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   418
    // sort all the fields into alphabetic order.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   419
    int total = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   420
    for (cJSON *i = item->child; i != NULL; i = i->next) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   421
        total++;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   422
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   423
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   424
    total--;  // don't include "hmac"
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   425
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   426
    cJSON **items = (cJSON **) calloc(total, sizeof (cJSON *));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   427
    if (!items) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   428
        return 0;  // oh well.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   429
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   430
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   431
    total = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   432
    for (cJSON *i = item->child; i != NULL; i = i->next) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   433
        if (strcmp(i->string, "hmac") == 0) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   434
            continue;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   435
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   436
        items[total++] = i;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   437
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   438
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   439
    qsort(items, total, sizeof (cJSON *), compare_cjson_by_fieldname);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   440
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   441
    int retval = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   442
    uint8_t digest[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   443
    HMAC_CTX ctx;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   444
    HMAC_CTX_init(&ctx);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   445
    if (HMAC_Init(&ctx, overviewhmac, 32, EVP_sha256())) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   446
        int i;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   447
        for (i = 0; i < total; i++) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   448
            cJSON *it = items[i];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   449
            if (!HMAC_Update(&ctx, (const unsigned char *) it->string, strlen(it->string))) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   450
                break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   451
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   452
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   453
            char strbuf[64];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   454
            const char *str = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   455
            switch (it->type) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   456
                case cJSON_False: str = "0"; break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   457
                case cJSON_True: str = "1"; break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   458
                case cJSON_Number: str = strbuf; snprintf(strbuf, sizeof (strbuf), "%d", (int) it->valuedouble); break;  // !!! FIXME: might be wrong.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   459
                case cJSON_String: str = it->valuestring; break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   460
                default: fprintf(stderr, "uhoh, can't HMAC this field ('%s')!\n", it->string); break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   461
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   462
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   463
            if (!HMAC_Update(&ctx, (const unsigned char *) str, strlen(str))) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   464
                break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   465
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   466
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   467
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   468
        unsigned int digestlen = sizeof (digest);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   469
        if ((i == total) && (HMAC_Final(&ctx, digest, &digestlen)) && (digestlen == sizeof (digest))) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   470
            uint8_t *expected = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   471
            if (base64_decode(base64hmac, -1, &expected) == sizeof (digest)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   472
                retval = (memcmp(digest, expected, sizeof (digest)) == 0) ? 1 : 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   473
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   474
            free(expected);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   475
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   476
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   477
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   478
    HMAC_CTX_cleanup(&ctx);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   479
    free(items);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   480
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   481
    return retval;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   482
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   483
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   484
static void dump_band(cJSON *band, const uint8_t *masterkey, const uint8_t *masterhmac, const uint8_t *overviewkey, const uint8_t *overviewhmac)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   485
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   486
    for (cJSON *i = band->child; i != NULL; i = i->next) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   487
        //dump_json(i);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   488
        cJSON *json;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   489
        uint8_t itemkey[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   490
        uint8_t itemhmac[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   491
        int itemkeysokay = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   492
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   493
        printf("uuid %s:\n", i->string);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   494
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   495
        if ((json = cJSON_GetObjectItem(i, "category")) != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   496
            const char *category = json->valuestring;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   497
            for (int i = 0; i < sizeof (category_map) / sizeof (category_map[0]); i++) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   498
                if (strcmp(category_map[i].idstr, category) == 0) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   499
                    category = category_map[i].name;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   500
                    break;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   501
                }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   502
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   503
            printf(" category: %s\n", category);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   504
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   505
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   506
        if ((json = cJSON_GetObjectItem(i, "created")) != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   507
            time_t t = (time_t) json->valuedouble;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   508
            printf(" created: %s", ctime(&t));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   509
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   510
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   511
        if ((json = cJSON_GetObjectItem(i, "updated")) != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   512
            time_t t = (time_t) json->valuedouble;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   513
            printf(" updated: %s", ctime(&t));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   514
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   515
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   516
        if ((json = cJSON_GetObjectItem(i, "tx")) != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   517
            time_t t = (time_t) json->valuedouble;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   518
            printf(" last tx: %s", ctime(&t));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   519
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   520
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   521
        printf(" trashed: %s\n", cJSON_IsTrue(cJSON_GetObjectItem(i, "trashed")) ? "true" : "false");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   522
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   523
        json = cJSON_GetObjectItem(i, "folder");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   524
        printf(" folder uuid: %s\n", json ? json->valuestring : "[none]");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   525
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   526
        if ((json = cJSON_GetObjectItem(i, "fave")) != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   527
            printf(" fave: %lu\n", (unsigned long) json->valuedouble);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   528
        } else {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   529
            printf(" fave: [no]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   530
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   531
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   532
        if ((json = cJSON_GetObjectItem(i, "hmac")) != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   533
            const char *base64hmac = json->valuestring;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   534
            const int valid = test_item_hmac(i, base64hmac, overviewhmac);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   535
            printf(" hmac: %s [%svalid]\n", base64hmac, valid ? "" : "in");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   536
        } else {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   537
            printf(" hmac: [none]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   538
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   539
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   540
        // !!! FIXME: lots of code dupe with master key decrypt.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   541
        if ((json = cJSON_GetObjectItem(i, "k")) != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   542
            const char *base64key = json->valuestring;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   543
            uint8_t *decoded = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   544
            const int decodedlen = base64_decode(base64key, -1, &decoded);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   545
            if ((decodedlen != -1) && (decodedlen > 32)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   546
                uint8_t digest[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   547
                unsigned int digestlen = sizeof (digest);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   548
                if (!HMAC(EVP_sha256(), masterhmac, 32, (const unsigned char *) decoded, decodedlen-digestlen, (unsigned char *) digest, &digestlen)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   549
                    fprintf(stderr, " [item key HMAC failed.]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   550
                } else if (digestlen != sizeof (digest)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   551
                    fprintf(stderr, "[item key HMAC is wrong size (got=%u expected=%u)].\n", digestlen, (unsigned int) sizeof (digest));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   552
                } else if (memcmp(digest, decoded + (decodedlen-sizeof (digest)), sizeof (digest)) != 0) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   553
                    fprintf(stderr, "[item key HMAC verification failed.]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   554
                } else {  // HMAC cleared.
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   555
                    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   556
                    const unsigned char *iv = (unsigned char *) (decoded);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   557
                    uint8_t *plaintext = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   558
                    int decryptedlen = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   559
                    int decryptedlen2 = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   560
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   561
                    if (!ctx) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   562
                        fprintf(stderr, "[item key EVP_CIPHER_CTX_new() failed.]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   563
                    } else if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char *) masterkey, iv)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   564
                        fprintf(stderr, "[item key EVP_DecryptInit_ex() failed.]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   565
                    } else if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   566
                        fprintf(stderr, "[item key EVP_CIPHER_CTX_set_padding() failed.]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   567
                    } else if ((plaintext = (uint8_t *) malloc(decodedlen)) == NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   568
                        fprintf(stderr, "[item key Out of memory.]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   569
                    } else if (!EVP_DecryptUpdate(ctx, plaintext, &decryptedlen, decoded + 16, decodedlen - 48)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   570
                        fprintf(stderr, "[item key EVP_DecryptUpdate() failed.]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   571
                    } else if (!EVP_DecryptFinal_ex(ctx, plaintext + decryptedlen, &decryptedlen2)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   572
                        fprintf(stderr, "[item key EVP_DecryptFinal_ex() failed.]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   573
                    } else if ((decryptedlen + decryptedlen2) != 64) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   574
                        fprintf(stderr, "[item key is wrong size.]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   575
                    } else {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   576
                        memcpy(itemkey, plaintext, 32);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   577
                        memcpy(itemhmac, plaintext + 32, 32);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   578
                        itemkeysokay = 1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   579
                    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   580
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   581
                    free(plaintext);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   582
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   583
                    if (ctx) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   584
                        EVP_CIPHER_CTX_cleanup(ctx);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   585
                    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   586
                }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   587
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   588
            free(decoded);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   589
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   590
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   591
        if ((json = cJSON_GetObjectItem(i, "o")) != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   592
            uint8_t *decrypted = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   593
            int decryptedlen = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   594
            if (decrypt_opdata_base64("o", json->valuestring, overviewkey, overviewhmac, &decrypted, &decryptedlen)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   595
                decrypted[decryptedlen] = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   596
                printf(" o: %s\n", decrypted);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   597
                free(decrypted);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   598
            } else {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   599
                printf(" o: [failed to decrypt]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   600
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   601
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   602
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   603
        if ((json = cJSON_GetObjectItem(i, "d")) != NULL) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   604
            uint8_t *decrypted = NULL;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   605
            int decryptedlen = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   606
            if (itemkeysokay && decrypt_opdata_base64("d", json->valuestring, itemkey, itemhmac, &decrypted, &decryptedlen)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   607
                decrypted[decryptedlen] = 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   608
                printf(" d: %s\n", decrypted);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   609
                free(decrypted);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   610
            } else {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   611
                printf(" d: [failed to decrypt]\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   612
            }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   613
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   614
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   615
        printf("\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   616
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   617
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   618
    printf("\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   619
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   620
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   621
static void dump_bands(const uint8_t *masterkey, const uint8_t *masterhmac, const uint8_t *overviewkey, const uint8_t *overviewhmac)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   622
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   623
    for (unsigned int i = 0; i < 16; i++) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   624
        char fname[16];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   625
        snprintf(fname, sizeof (fname), "band_%X.js", i);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   626
        cJSON *band = load_json(fname);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   627
        if (band) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   628
            printf("\nBand %s...\n\n", fname);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   629
            dump_band(band, masterkey, masterhmac, overviewkey, overviewhmac);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   630
            cJSON_Delete(band);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   631
        }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   632
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   633
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   634
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   635
int main(int argc, char **argv)
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   636
{
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   637
    OpenSSL_add_all_algorithms();
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   638
    ERR_load_crypto_strings();
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   639
    OPENSSL_config(NULL);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   640
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   641
    if (argc != 3) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   642
        fprintf(stderr, "\n\nUSAGE: %s </path/to/1Password.opvault> <keychain password>\n\n", argv[0]);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   643
        return 2;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   644
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   645
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   646
    const char *opvaultpath = argv[1];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   647
    const char *password = argv[2];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   648
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   649
    if (chdir(opvaultpath) == -1) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   650
        fprintf(stderr, "chdir(\"%s\") failed: %s\n", opvaultpath, strerror(errno));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   651
        return 1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   652
    } else if (chdir("default") == -1) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   653
        fprintf(stderr, "chdir(\"%s/default\") failed: %s\n", opvaultpath, strerror(errno));
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   654
        return 1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   655
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   656
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   657
    cJSON *profile = load_json("profile.js");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   658
    if (!profile) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   659
        fprintf(stderr, "load_json(\"profile.js\") failed.\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   660
        return 1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   661
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   662
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   663
    printf("profile : "); dump_json(profile); printf("\n");
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   664
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   665
    uint8_t masterkey[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   666
    uint8_t masterhmac[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   667
    uint8_t overviewkey[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   668
    uint8_t overviewhmac[32];
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   669
    if (!prepare_keys(profile, password, masterkey, masterhmac, overviewkey, overviewhmac)) {
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   670
        return 1;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   671
    }
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   672
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   673
    cJSON_Delete(profile);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   674
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   675
    dump_folders(overviewkey, overviewhmac);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   676
    dump_bands(masterkey, masterhmac, overviewkey, overviewhmac);
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   677
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   678
    return 0;
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   679
}
1390348facc7 Command line tool that decrypts an OPVault keychain and dumps it to stdout.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   680