| Index: src/platform/vboot_reference/utils/signature_digest.c
|
| diff --git a/src/platform/vboot_reference/utils/signature_digest.c b/src/platform/vboot_reference/utils/signature_digest.c
|
| index 100f7ecbf6fa3957ee9c4aa104889348fcf48b47..96cc5529762b98216c98e94d5c7fa43330eaeb96 100644
|
| --- a/src/platform/vboot_reference/utils/signature_digest.c
|
| +++ b/src/platform/vboot_reference/utils/signature_digest.c
|
| @@ -1,17 +1,13 @@
|
| /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
|
| * Use of this source code is governed by a BSD-style license that can be
|
| * found in the LICENSE file.
|
| - *
|
| - * Utility that outputs the message digest of the contents of a file in a
|
| - * format that can be used as input to OpenSSL for an RSA signature.
|
| - * Needed until the stable OpenSSL release supports SHA-256/512 digests for
|
| - * RSA signatures.
|
| - * Outputs DigestInfo || Digest where DigestInfo is the OID depending on the
|
| - * choice of the hash algorithm (see padding.c).
|
| - *
|
| */
|
|
|
| #include "signature_digest.h"
|
| +#define OPENSSL_NO_SHA
|
| +#include <openssl/engine.h>
|
| +#include <openssl/pem.h>
|
| +#include <openssl/rsa.h>
|
|
|
| #include <stdio.h>
|
| #include <stdlib.h>
|
| @@ -20,49 +16,59 @@
|
| #include "padding.h"
|
| #include "sha.h"
|
| #include "sha_utility.h"
|
| +#include "utility.h"
|
|
|
| uint8_t* PrependDigestInfo(int algorithm, uint8_t* digest) {
|
| const int digest_size = hash_size_map[algorithm];
|
| const int digestinfo_size = digestinfo_size_map[algorithm];
|
| const uint8_t* digestinfo = hash_digestinfo_map[algorithm];
|
| - uint8_t* p = malloc(digestinfo_size + digest_size);
|
| - memcpy(p, digestinfo, digestinfo_size);
|
| - memcpy(p + digestinfo_size, digest, digest_size);
|
| + uint8_t* p = Malloc(digestinfo_size + digest_size);
|
| + Memcpy(p, digestinfo, digestinfo_size);
|
| + Memcpy(p + digestinfo_size, digest, digest_size);
|
| return p;
|
| }
|
|
|
| -int main(int argc, char* argv[]) {
|
| - int i, algorithm;
|
| - uint8_t* digest = NULL;
|
| - uint8_t* signature = NULL;
|
| +uint8_t* SignatureDigest(const uint8_t* buf, int len, int algorithm) {
|
| uint8_t* info_digest = NULL;
|
| + uint8_t* digest = NULL;
|
|
|
| - if (argc != 3) {
|
| - fprintf(stderr, "Usage: %s <algorithm> <input file>\n\n",
|
| - argv[0]);
|
| - fprintf(stderr, "where <algorithm> is the signature algorithm to use:\n");
|
| - for(i = 0; i<kNumAlgorithms; i++)
|
| - fprintf(stderr, "\t%d for %s\n", i, algo_strings[i]);
|
| - return -1;
|
| - }
|
| -
|
| - algorithm = atoi(argv[1]);
|
| if (algorithm >= kNumAlgorithms) {
|
| - fprintf(stderr, "Invalid Algorithm!\n");
|
| - goto failure;
|
| + fprintf(stderr, "SignatureDigest() called with invalid algorithm!\n");
|
| + } else if ((digest = DigestBuf(buf, len, algorithm))) {
|
| + info_digest = PrependDigestInfo(algorithm, digest);
|
| }
|
| + Free(digest);
|
| + return info_digest;
|
| +}
|
|
|
| - if (!(digest = DigestFile(argv[2], algorithm)))
|
| - goto failure;
|
| -
|
| - info_digest = PrependDigestInfo(algorithm, digest);
|
| - write(1, info_digest, hash_size_map[algorithm] +
|
| - digestinfo_size_map[algorithm]);
|
| -
|
| -failure:
|
| - free(digest);
|
| - free(info_digest);
|
| - free(signature);
|
| -
|
| - return 0;
|
| +uint8_t* SignatureBuf(const uint8_t* buf, int len, const char* key_file,
|
| + int algorithm) {
|
| + FILE* key_fp = NULL;
|
| + RSA* key = NULL;
|
| + uint8_t* signature = NULL;
|
| + uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
|
| + int signature_digest_len = (hash_size_map[algorithm] +
|
| + digestinfo_size_map[algorithm]);
|
| + key_fp = fopen(key_file, "r");
|
| + if (!key_fp) {
|
| + fprintf(stderr, "SignatureBuf(): Couldn't open key file: %s\n", key_file);
|
| + return NULL;
|
| + }
|
| + if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
|
| + signature = (uint8_t*) Malloc(siglen_map[algorithm]);
|
| + else
|
| + fprintf(stderr, "SignatureBuf(): Couldn't read private key from file: %s\n",
|
| + key_file);
|
| + if (signature) {
|
| + if (-1 == RSA_private_encrypt(signature_digest_len, /* Input length. */
|
| + signature_digest, /* Input data. */
|
| + signature, /* Output signature. */
|
| + key, /* Key to use. */
|
| + RSA_PKCS1_PADDING)) /* Padding to use. */
|
| + fprintf(stderr, "SignatureBuf(): RSA_private_encrypt() failed.\n");
|
| + }
|
| + if (key)
|
| + RSA_free(key);
|
| + Free(signature_digest);
|
| + return signature;
|
| }
|
|
|