keystore_cli.cpp revision a91203b08350b2fc7efda5b1eab39e7541476b3a
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License.
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License.
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <stdio.h>
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <stdint.h>
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <string.h>
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/types.h>
2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/socket.h>
2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <cutils/sockets.h>
2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "keystore.h"
2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic const char* responses[] = {
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    NULL,
2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    /* [NO_ERROR]           = */ "No error",
306f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopian    /* [LOCKED]             = */ "Locked",
3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    /* [UNINITIALIZED]      = */ "Uninitialized",
3214d2747c7e54037e267bcff78b29e65b2181f0faNicolas Catania    /* [SYSTEM_ERROR]       = */ "System error",
336f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopian    /* [PROTOCOL_ERROR]     = */ "Protocol error",
346f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopian    /* [PERMISSION_DENIED]  = */ "Permission denied",
3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    /* [KEY_NOT_FOUND]      = */ "Key not found",
3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    /* [VALUE_CORRUPTED]    = */ "Value corrupted",
376f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopian    /* [UNDEFINED_ACTION]   = */ "Undefined action",
387562408b2261d38415453378b6188f74fda99d88Mathias Agopian    /* [WRONG_PASSWORD]     = */ "Wrong password (last chance)",
397562408b2261d38415453378b6188f74fda99d88Mathias Agopian    /* [WRONG_PASSWORD + 1] = */ "Wrong password (2 tries left)",
407562408b2261d38415453378b6188f74fda99d88Mathias Agopian    /* [WRONG_PASSWORD + 2] = */ "Wrong password (3 tries left)",
417562408b2261d38415453378b6188f74fda99d88Mathias Agopian    /* [WRONG_PASSWORD + 3] = */ "Wrong password (4 tries left)",
421d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania};
431d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania
4410dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissenint main(int argc, char* argv[])
451d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania{
4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (argc < 2) {
4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        printf("Usage: %s action [parameter ...]\n", argv[0]);
4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return 0;
4989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
51a64c8c79af1a15911c55306d83a797fa50969f77niko    int sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   SOCK_STREAM);
5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (sock == -1) {
5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        puts("Failed to connect");
5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return 1;
5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    send(sock, argv[1], 1, 0);
5989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint8_t bytes[65536];
6014d2747c7e54037e267bcff78b29e65b2181f0faNicolas Catania    for (int i = 2; i < argc; ++i) {
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint16_t length = strlen(argv[i]);
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        bytes[0] = length >> 8;
6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        bytes[1] = length;
6414d2747c7e54037e267bcff78b29e65b2181f0faNicolas Catania        send(sock, &bytes, 2, 0);
6589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        send(sock, argv[i], length, 0);
6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    shutdown(sock, SHUT_WR);
6889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
6989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint8_t code;
7089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (recv(sock, &code, 1, 0) != 1) {
7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        puts("Failed to receive");
7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return 1;
7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    printf("%d %s\n", code , responses[code] ? responses[code] : "Unknown");
7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int i;
7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    while ((i = recv(sock, &bytes[0], 1, 0)) == 1) {
77a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        int length;
78a64c8c79af1a15911c55306d83a797fa50969f77niko        int offset;
79a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        if ((i = recv(sock, &bytes[1], 1, 0)) != 1) {
80a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania            puts("Failed to receive");
81a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania            return 1;
82a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        }
83a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        length = bytes[0] << 8 | bytes[1];
84a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        for (offset = 0; offset < length; offset += i) {
85a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania            i = recv(sock, &bytes[offset], length - offset, 0);
86a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania            if (i <= 0) {
87a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania                puts("Failed to receive");
88a64c8c79af1a15911c55306d83a797fa50969f77niko                return 1;
89d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko            }
90a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        }
91a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        fwrite(bytes, 1, length, stdout);
92a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        puts("");
93a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
94a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    return 0;
95a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania}
96a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania