ocsp_req_create.c
Go to the documentation of this file.
1 /**
2  * @file ocsp_req_create.c
3  * @brief OCSP request generation
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL OCSP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ocsp/ocsp_req_create.h"
36 #include "ocsp/ocsp_req_format.h"
37 #include "encoding/asn1.h"
38 #include "debug.h"
39 
40 //Check crypto library configuration
41 #if (OCSP_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Generate an OCSP request
46  * @param[in] certInfo Certificate to be checked
47  * @param[in] issuerCertInfo Issuer's certificate
48  * @param[in] nonce Pointer to the random nonce (optional parameter)
49  * @param[in] nonceLen Length of the nonce, in bytes (optional parameter)
50  * @param[out] output Buffer where to store the ASN.1 structure
51  * @param[out] written Length of the resulting ASN.1 structure
52  * @return Error code
53  **/
54 
56  const X509CertInfo *issuerCertInfo, const uint8_t *nonce,
57  size_t nonceLen, uint8_t *output, size_t *written)
58 {
59  error_t error;
60  size_t n;
61  OcspRequest request;
62  OcspCertId *certId;
63  const HashAlgo *hashAlgo;
64  const X509SubjectPublicKeyInfo *issuerPublicKeyInfo;
65  uint8_t issuerNameHash[MAX_HASH_DIGEST_SIZE];
66  uint8_t issuerKeyHash[MAX_HASH_DIGEST_SIZE];
67 
68  //Clear OCSPRequest structure
69  osMemset(&request, 0, sizeof(OcspRequest));
70 
71  //Set the version of the protocol
73 
74  //OCSP requests conformant to this profile must include only one request
75  //in the RequestList structure (refer to RFC 5019, section 2.1.1)
76  request.tbsRequest.numRequests = 1;
77 
78  //Point to the certificate identifier
79  certId = &request.tbsRequest.requestList[0].reqCert;
80 
81  //Select the relevant hash algorithm that will be used to generate the
82  //IssuerNameHash and IssuerKeyHash values
83  hashAlgo = ocspSelectHashAlgo();
84  //Invalid hash algorithm?
85  if(hashAlgo == NULL)
87 
88  //Digest the DER encoding of the issuer's name field in the certificate
89  //being checked (refer to RFC 6960, section 4.1.1)
90  error = hashAlgo->compute(certInfo->tbsCert.issuer.raw.value,
91  certInfo->tbsCert.issuer.raw.length, issuerNameHash);
92  //Any error to report?
93  if(error)
94  return error;
95 
96  //Point to the issuer's public key
97  issuerPublicKeyInfo = &issuerCertInfo->tbsCert.subjectPublicKeyInfo;
98 
99  //Digest the value (excluding tag and length) of the subject public key
100  //field in the issuer's certificate
101  error = hashAlgo->compute(issuerPublicKeyInfo->rawSubjectPublicKey.value,
102  issuerPublicKeyInfo->rawSubjectPublicKey.length, issuerKeyHash);
103  //Any error to report?
104  if(error)
105  return error;
106 
107  //Set hash algorithm OID
108  certId->hashAlgo.value = hashAlgo->oid;
109  certId->hashAlgo.length = hashAlgo->oidSize;
110 
111  //Set the hash of the issuer's distinguished name (DN)
112  certId->issuerNameHash.value = issuerNameHash;
113  certId->issuerNameHash.length = hashAlgo->digestSize;
114 
115  //Set the hash of the issuer's public key
116  certId->issuerKeyHash.value = issuerKeyHash;
117  certId->issuerKeyHash.length = hashAlgo->digestSize;
118 
119  //Specify the serial number of the certificate for which status is being
120  //requested
121  certId->serialNumber.value = certInfo->tbsCert.serialNumber.value;
122  certId->serialNumber.length = certInfo->tbsCert.serialNumber.length;
123 
124  //The Nonce extension is used to cryptographically binds a request and a
125  //response to prevent replay attacks (refer to RFC 8954, section 2.1)
126  request.tbsRequest.requestExtensions.nonce.value = nonce;
127  request.tbsRequest.requestExtensions.nonce.length = nonceLen;
128 
129  //Format OCSPRequest structure
130  error = ocspFormatRequest(&request, output, &n);
131  //Any error to report?
132  if(error)
133  return error;
134 
135  //Debug message
136  TRACE_DEBUG("OCSP request (%" PRIuSIZE " bytes):\r\n", n);
137  //Dump OCSP request
138  asn1DumpObject(output, n, 0);
139 
140  //Total number of bytes that have been written
141  *written = n;
142 
143  //Successful processing
144  return NO_ERROR;
145 }
146 
147 #endif
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:706
ASN.1 (Abstract Syntax Notation One)
#define PRIuSIZE
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_UNSUPPORTED_HASH_ALGO
Definition: error.h:130
@ NO_ERROR
Success.
Definition: error.h:44
#define MAX_HASH_DIGEST_SIZE
const HashAlgo * ocspSelectHashAlgo(void)
Hash algorithm selection.
Definition: ocsp_common.c:52
@ OCSP_VERSION_1
Definition: ocsp_common.h:106
error_t ocspCreateRequest(const X509CertInfo *certInfo, const X509CertInfo *issuerCertInfo, const uint8_t *nonce, size_t nonceLen, uint8_t *output, size_t *written)
Generate an OCSP request.
OCSP request generation.
error_t ocspFormatRequest(const OcspRequest *request, uint8_t *output, size_t *written)
Format OCSPRequest structure.
OCSP request formatting.
#define osMemset(p, value, length)
Definition: os_port.h:135
Common interface for hash algorithms.
Definition: crypto.h:1014
HashAlgoCompute compute
Definition: crypto.h:1023
size_t oidSize
Definition: crypto.h:1017
size_t digestSize
Definition: crypto.h:1020
const uint8_t * oid
Definition: crypto.h:1016
CertID structure.
Definition: ocsp_common.h:142
X509OctetString serialNumber
Definition: ocsp_common.h:146
X509OctetString hashAlgo
Definition: ocsp_common.h:143
X509OctetString issuerNameHash
Definition: ocsp_common.h:144
X509OctetString issuerKeyHash
Definition: ocsp_common.h:145
X509OctetString nonce
Definition: ocsp_common.h:178
OCSPRequest structure.
Definition: ocsp_common.h:200
OcspTbsRequest tbsRequest
Definition: ocsp_common.h:201
OcspCertId reqCert
Definition: ocsp_common.h:166
OcspVersion version
Definition: ocsp_common.h:188
OcspExtensions requestExtensions
Definition: ocsp_common.h:191
uint_t numRequests
Definition: ocsp_common.h:189
OcspSingleRequest requestList[OCSP_MAX_REQUESTS]
Definition: ocsp_common.h:190
X.509 certificate.
Definition: x509_common.h:1064
X509TbsCertificate tbsCert
Definition: x509_common.h:1065
X509OctetString raw
Definition: x509_common.h:669
const uint8_t * value
Definition: x509_common.h:647
const uint8_t * value
Definition: x509_common.h:658
Subject Public Key Information extension.
Definition: x509_common.h:783
X509OctetString rawSubjectPublicKey
Definition: x509_common.h:786
X509SerialNumber serialNumber
Definition: x509_common.h:1049
X509SubjectPublicKeyInfo subjectPublicKeyInfo
Definition: x509_common.h:1054