• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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