1 /*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <openssl/asn1.h>
11 #include <openssl/digest.h>
12 #include <openssl/err.h>
13 #include <openssl/evp.h>
14 #include <openssl/mem.h>
15 #include <openssl/obj.h>
16 #include <openssl/x509.h>
17
18 #include <limits.h>
19
20 #include "internal.h"
21
ASN1_item_sign(const ASN1_ITEM * it,X509_ALGOR * algor1,X509_ALGOR * algor2,ASN1_BIT_STRING * signature,void * asn,EVP_PKEY * pkey,const EVP_MD * type)22 int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
23 ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
24 const EVP_MD *type) {
25 if (signature->type != V_ASN1_BIT_STRING) {
26 OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
27 return 0;
28 }
29 EVP_MD_CTX ctx;
30 EVP_MD_CTX_init(&ctx);
31 if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
32 EVP_MD_CTX_cleanup(&ctx);
33 return 0;
34 }
35 return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
36 }
37
ASN1_item_sign_ctx(const ASN1_ITEM * it,X509_ALGOR * algor1,X509_ALGOR * algor2,ASN1_BIT_STRING * signature,void * asn,EVP_MD_CTX * ctx)38 int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
39 X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
40 void *asn, EVP_MD_CTX *ctx) {
41 int ret = 0;
42 uint8_t *in = NULL, *out = NULL;
43
44 {
45 if (signature->type != V_ASN1_BIT_STRING) {
46 OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
47 goto err;
48 }
49
50 // Write out the requested copies of the AlgorithmIdentifier.
51 if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) {
52 goto err;
53 }
54 if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) {
55 goto err;
56 }
57
58 int in_len = ASN1_item_i2d(reinterpret_cast<ASN1_VALUE *>(asn), &in, it);
59 if (in_len < 0) {
60 goto err;
61 }
62
63 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
64 size_t out_len = EVP_PKEY_size(pkey);
65 if (out_len > INT_MAX) {
66 OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW);
67 goto err;
68 }
69
70 out = reinterpret_cast<uint8_t *>(OPENSSL_malloc(out_len));
71 if (out == NULL) {
72 goto err;
73 }
74
75 if (!EVP_DigestSign(ctx, out, &out_len, in, in_len)) {
76 OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
77 goto err;
78 }
79
80 ASN1_STRING_set0(signature, out, (int)out_len);
81 out = NULL;
82 signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
83 signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
84 ret = (int)out_len;
85 }
86
87 err:
88 EVP_MD_CTX_cleanup(ctx);
89 OPENSSL_free(in);
90 OPENSSL_free(out);
91 return ret;
92 }
93