Coverage Report

Created: 2026-02-14 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/x509/a_sign.cc
Line
Count
Source
1
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/asn1.h>
16
#include <openssl/digest.h>
17
#include <openssl/err.h>
18
#include <openssl/evp.h>
19
#include <openssl/mem.h>
20
#include <openssl/obj.h>
21
#include <openssl/span.h>
22
#include <openssl/x509.h>
23
24
#include <limits.h>
25
26
#include "../internal.h"
27
#include "../mem_internal.h"
28
#include "internal.h"
29
30
31
using namespace bssl;
32
33
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
34
                   ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
35
0
                   const EVP_MD *type) {
36
0
  if (signature->type != V_ASN1_BIT_STRING) {
37
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
38
0
    return 0;
39
0
  }
40
0
  ScopedEVP_MD_CTX ctx;
41
0
  if (!EVP_DigestSignInit(ctx.get(), nullptr, type, nullptr, pkey)) {
42
0
    return 0;
43
0
  }
44
0
  return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx.get());
45
0
}
46
47
int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
48
                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
49
0
                       void *asn, EVP_MD_CTX *ctx) {
50
  // Historically, this function called |EVP_MD_CTX_cleanup| on return. Some
51
  // callers rely on this to avoid memory leaks.
52
0
  Cleanup cleanup = [&] { EVP_MD_CTX_cleanup(ctx); };
53
54
  // Write out the requested copies of the AlgorithmIdentifier. This may modify
55
  // |asn|, so we must do it first.
56
0
  if ((algor1 != nullptr && !x509_digest_sign_algorithm(ctx, algor1)) ||
57
0
      (algor2 != nullptr && !x509_digest_sign_algorithm(ctx, algor2))) {
58
0
    return 0;
59
0
  }
60
61
0
  uint8_t *in = nullptr;
62
0
  int in_len = ASN1_item_i2d(reinterpret_cast<ASN1_VALUE *>(asn), &in, it);
63
0
  if (in_len < 0) {
64
0
    return 0;
65
0
  }
66
0
  UniquePtr<uint8_t> free_in(in);
67
68
0
  return x509_sign_to_bit_string(ctx, signature, Span(in, in_len));
69
0
}
70
71
int bssl::x509_sign_to_bit_string(EVP_MD_CTX *ctx, ASN1_BIT_STRING *out,
72
0
                                  Span<const uint8_t> in) {
73
0
  if (out->type != V_ASN1_BIT_STRING) {
74
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
75
0
    return 0;
76
0
  }
77
78
0
  EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
79
0
  size_t sig_len = EVP_PKEY_size(pkey);
80
0
  if (sig_len > INT_MAX) {
81
    // Ensure the signature will fit in |out|.
82
0
    OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW);
83
0
    return 0;
84
0
  }
85
0
  Array<uint8_t> sig;
86
0
  if (!sig.Init(sig_len)) {
87
0
    return 0;
88
0
  }
89
90
0
  if (!EVP_DigestSign(ctx, sig.data(), &sig_len, in.data(), in.size())) {
91
0
    OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
92
0
    return 0;
93
0
  }
94
0
  sig.Shrink(sig_len);
95
96
0
  uint8_t *sig_data;
97
0
  sig.Release(&sig_data, &sig_len);
98
0
  ASN1_STRING_set0(out, sig_data, static_cast<int>(sig_len));
99
0
  out->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
100
0
  out->flags |= ASN1_STRING_FLAG_BITS_LEFT;
101
0
  return static_cast<int>(sig_len);
102
0
}