scep_client_resp_parse.c
Go to the documentation of this file.
1 /**
2  * @file scep_client_resp_parse.c
3  * @brief SCEP response parsing
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 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.5.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SCEP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "scep/scep_client.h"
37 #include "scep/scep_client_misc.h"
38 #include "scep/scep_debug.h"
39 #include "pkcs7/pkcs7_parse.h"
40 #include "pkcs7/pkcs7_decrypt.h"
42 #include "pkix/x509_cert_parse.h"
43 #include "encoding/asn1.h"
44 #include "encoding/oid.h"
45 #include "str.h"
46 #include "debug.h"
47 
48 //Check crypto library configuration
49 #if (SCEP_CLIENT_SUPPORT == ENABLED)
50 
51 
52 /**
53  * @brief Parse GetCACaps response
54  * @param[in] context Pointer to the SCEP client context
55  * @return Error code
56  **/
57 
59 {
60  char_t *p;
61  char_t *token;
62  char_t *keyword;
63 
64  //A client that receives an empty message or an HTTP error should interpret
65  //the response as if none of the capabilities listed are supported by the CA
66  //(refer to RFC 8894, section 3.5.2)
67  context->caCaps = SCEP_CA_CAPS_NONE;
68 
69  //Check HTTP status code
70  if(HTTP_STATUS_CODE_2YZ(context->statusCode))
71  {
72  //Check whether the body of the response is truncated
73  if(context->bufferLen >= SCEP_CLIENT_BUFFER_SIZE)
75 
76  //Properly terminate the body with a NULL character
77  context->buffer[context->bufferLen] = '\0';
78 
79  //The response for a GetCACaps message is a list of CA capabilities
80  token = osStrtok_r((char_t *) context->buffer, "\n", &p);
81 
82  //Parse the list of keywords
83  while(token != NULL)
84  {
85  //Clients must accept the standard HTTP-style text delimited by
86  //<CR><LF> as well as the text delimited by <LF>
87  keyword = strTrimWhitespace(token);
88 
89  //Clients should ignore the text case when processing the message
90  if(osStrcasecmp(keyword, "AES") == 0)
91  {
92  //CA supports the AES128-CBC encryption algorithm
93  context->caCaps |= SCEP_CA_CAPS_AES;
94  }
95  else if(osStrcasecmp(keyword, "DES3") == 0)
96  {
97  //CA supports the triple DES-CBC encryption algorithm
98  context->caCaps |= SCEP_CA_CAPS_DES3;
99  }
100  else if(osStrcasecmp(keyword, "GetNextCACert") == 0)
101  {
102  //CA supports the GetNextCACert message
103  context->caCaps |= SCEP_CA_CAPS_GET_NEXT_CA_CERT;
104  }
105  else if(osStrcasecmp(keyword, "POSTPKIOperation") == 0)
106  {
107  //CA supports PKIOPeration messages sent via HTTP POST
108  context->caCaps |= SCEP_CA_CAPS_POST_PKI_OPERATION;
109  }
110  else if(osStrcasecmp(keyword, "Renewal") == 0)
111  {
112  //CA supports the Renewal CA operation
113  context->caCaps |= SCEP_CA_CAPS_RENEWAL;
114  }
115  else if(osStrcasecmp(keyword, "SHA-1") == 0)
116  {
117  //CA supports the SHA-1 hashing algorithm
118  context->caCaps |= SCEP_CA_CAPS_SHA1;
119  }
120  else if(osStrcasecmp(keyword, "SHA-256") == 0)
121  {
122  //CA supports the SHA-256 hashing algorithm
123  context->caCaps |= SCEP_CA_CAPS_SHA256;
124  }
125  else if(osStrcasecmp(keyword, "SHA-512") == 0)
126  {
127  //CA supports the SHA-512 hashing algorithm
128  context->caCaps |= SCEP_CA_CAPS_SHA512;
129  }
130  else if(osStrcasecmp(keyword, "SCEPStandard") == 0)
131  {
132  //CA supports all mandatory-to-implement sections of the SCEP
133  //standard. This keyword implies "AES", "POSTPKIOperation", and
134  //"SHA-256"
137  }
138  else
139  {
140  //A client must be able to accept and ignore any unknown keywords
141  //that might be sent by a CA (refer to RFC 8894, section 3.5.2)
142  }
143 
144  //Get the next keyword
145  token = osStrtok_r(NULL, "\n", &p);
146  }
147  }
148 
149  //Successful processing
150  return NO_ERROR;
151 }
152 
153 
154 /**
155  * @brief Parse GetCACert response
156  * @param[in] context Pointer to the SCEP client context
157  * @return Error code
158  **/
159 
161 {
162  error_t error;
163 
164  //Initialize status code
165  error = NO_ERROR;
166 
167  //Clear CA certificate first
168  context->caCertLen = 0;
169 
170  //Check HTTP status code
171  if(HTTP_STATUS_CODE_2YZ(context->statusCode))
172  {
173  //The response for GetCACert is different between the case where the CA
174  //directly communicates with the client during the enrolment and the case
175  //where an intermediate CA exists and the client communicates with this
176  //CA during the enrolment (refer to RFC 8894, section 4.2.1)
177  if(osStrcmp(context->contentType, "application/x-x509-ca-cert") == 0)
178  {
179  //Check the length of the CA certificate
180  if(context->bufferLen > 0 &&
181  context->bufferLen <= SCEP_CLIENT_MAX_CA_CERT_LEN)
182  {
183  //If the CA does not have any intermediate CA certificates, the
184  //response consists of a single X.509 CA certificate
185  osMemcpy(context->caCert, context->buffer, context->bufferLen);
186  context->caCertLen = context->bufferLen;
187  }
188  else
189  {
190  //Report an error
191  error = ERROR_RESPONSE_TOO_LARGE;
192  }
193  }
194  else if(osStrcmp(context->contentType, "application/x-x509-ca-ra-cert") == 0)
195  {
196  size_t n;
197  Pkcs7ContentInfo contentInfo;
198  Pkcs7SignedData signedData;
199 
200  //If the CA has intermediate CA certificates, the response consists of
201  //a degenerate certificates-only CMS SignedData message containing the
202  //certificates, with the intermediate CA certificate(s) as the leaf
203  //certificate(s)
204  error = pkcs7ParseContentInfo(context->buffer, context->bufferLen, &n,
205  &contentInfo);
206 
207  //Check status code
208  if(!error)
209  {
210  //Parse signed-data content
211  error = pkcs7ParseSignedData(contentInfo.content.value,
212  contentInfo.content.length, &signedData);
213  }
214 
215  //Check status code
216  if(!error)
217  {
218  //Check the length of the certificate chain
219  if(signedData.certificates.raw.length > 0 &&
221  {
222  //Save the CA certificate chain
223  osMemcpy(context->caCert, signedData.certificates.raw.value,
224  signedData.certificates.raw.length);
225 
226  //Save the length of the CA certificate chain
227  context->caCertLen = signedData.certificates.raw.length;
228  }
229  else
230  {
231  //Report an error
232  error = ERROR_RESPONSE_TOO_LARGE;
233  }
234  }
235  }
236  else
237  {
238  //Report an error
239  error = ERROR_INVALID_RESPONSE;
240  }
241  }
242  else
243  {
244  //Report an error
245  error = ERROR_UNEXPECTED_STATUS;
246  }
247 
248  //Check status code
249  if(!error)
250  {
251  //After the client gets the CA certificate, it should authenticate it
252  //(refer to RFC 8894, section 2.2)
253  error = scepClientVerifyCaCert(context);
254  }
255 
256  //Return status code
257  return error;
258 }
259 
260 
261 /**
262  * @brief Parse CertRep response
263  * @param[in] context Pointer to the SCEP client context
264  * @return Error code
265  **/
266 
268 {
269  error_t error;
270 
271  //Check HTTP status code
272  if(HTTP_STATUS_CODE_2YZ(context->statusCode))
273  {
274  //The response will have a Content-Type of "application/x-pki-message"
275  //(refer to RFC 8894, section 4.3.1)
276  if(osStrcmp(context->contentType, "application/x-pki-message") == 0)
277  {
278  //The basic building block of all secured SCEP messages is the SCEP
279  //pkiMessage (refer to RFC 8894, section 3.2)
280  error = scepClientParsePkiMessage(context, context->buffer,
281  context->bufferLen);
282  }
283  else
284  {
285  //Report an error
286  error = ERROR_INVALID_RESPONSE;
287  }
288  }
289  else
290  {
291  //The text content type is used for message content that is primarily in
292  //human-readable text character format
293  if(osStrncmp(context->contentType, "text/", 5) == 0)
294  {
295  //Properly terminate the string with a NULL character
296  context->buffer[context->bufferLen] = '\0';
297  //Dump HTTP response body
298  TRACE_DEBUG("%s", context->buffer);
299  }
300 
301  //Report an error
302  error = ERROR_UNEXPECTED_STATUS;
303  }
304 
305  //Return status code
306  return error;
307 }
308 
309 
310 /**
311  * @brief Parse PKI message
312  * @param[in] context Pointer to the SCEP client context
313  * @param[in] data Pointer to the PKI message to parse
314  * @param[in] length Length of the PKI message
315  * @return Error code
316  **/
317 
319  const uint8_t *data, size_t length)
320 {
321  error_t error;
322  size_t n;
323  uint_t messageType;
324  uint_t pkiStatus;
325  Pkcs7ContentInfo contentInfo;
326  Pkcs7SignedData signedData;
327  Pkcs7SignerInfo signerInfo;
328  Pkcs7Attribute attribute;
329  X509CertInfo *certInfo;
330  Asn1Tag tag;
331 
332  //Debug message
333  TRACE_DEBUG("pkiMessage (%" PRIuSIZE " bytes):\r\n", length);
335 
336  //The general syntax for content exchanged between entities associates a
337  //content type with content (refer to RFC 2315, section 7)
338  error = pkcs7ParseContentInfo(data, length, &n, &contentInfo);
339  //Any error to report?
340  if(error)
341  return error;
342 
343  //The basic building block of all secured SCEP messages is the SCEP
344  //pkiMessage. It consists of a CMS SignedData content type (refer to
345  //RFC 8894, section 3.2)
346  if(OID_COMP(contentInfo.contentType.value, contentInfo.contentType.length,
347  PKCS7_SIGNED_DATA_OID) != 0)
348  {
349  return ERROR_INVALID_TYPE;
350  }
351 
352  //Parse signed-data content
353  error = pkcs7ParseSignedData(contentInfo.content.value,
354  contentInfo.content.length, &signedData);
355  //Any error to report?
356  if(error)
357  return error;
358 
359  //Allocate a memory buffer to store X.509 certificate info
360  certInfo = cryptoAllocMem(sizeof(X509CertInfo));
361 
362  //Successful memory allocation?
363  if(certInfo != NULL)
364  {
365  //The recipient may obtain the correct public key for the signer by any
366  //means, but the preferred method is from a certificate obtained from the
367  //SignedData certificates field
368  error = scepClientParseCaCert(context, certInfo);
369 
370  //Check status code
371  if(!error)
372  {
373  //Search a list of per-signer informations for a matching signer
374  error = pkcs7FindSigner(&signedData.signerInfos, certInfo,
375  &signerInfo);
376  }
377 
378  //Check status code
379  if(!error)
380  {
381  //Verify signature over signed-data content
382  error = pkcs7VerifySignedData(&signedData, &signerInfo, certInfo);
383  }
384 
385  //Release previously allocated memory
386  cryptoFreeMem(certInfo);
387  }
388  else
389  {
390  //Failed to allocate memory
391  error = ERROR_OUT_OF_MEMORY;
392  }
393 
394  //Any error to report?
395  if(error)
396  return error;
397 
398  //All messages must contain a transactionID attribute
401  sizeof(SCEP_TRANSACTION_ID_OID), &attribute);
402  //Any error to report?
403  if(error)
404  return error;
405 
406  //The attribute is encoded as PrintableString
407  if(attribute.type != ASN1_TYPE_PRINTABLE_STRING)
408  return ERROR_INVALID_SYNTAX;
409 
410  //The transactionID must be used for all PKI messages exchanged for a given
411  //operation
412  if(attribute.data.length != osStrlen(context->transactionId) ||
413  osMemcmp(attribute.data.value, context->transactionId,
414  attribute.data.length) != 0)
415  {
416  return ERROR_INVALID_SYNTAX;
417  }
418 
419  //The messageType attribute specifies the type of operation performed by the
420  //transaction. This attribute must be included in all PKI messages (refer to
421  //RFC 8894, section 3.2.1.2)
424  sizeof(SCEP_MESSAGE_TYPE_OID), &attribute);
425  //Any error to report?
426  if(error)
427  return error;
428 
429  //The attribute is encoded as a PrintableString
430  if(attribute.type != ASN1_TYPE_PRINTABLE_STRING)
431  return ERROR_INVALID_SYNTAX;
432 
433  //The attribute value is a numeric text string
434  error = x509ParseInt(attribute.data.value, attribute.data.length,
435  &messageType);
436  //Any error to report?
437  if(error)
438  return error;
439 
440  //Debug message
441  scepDumpMessageType(messageType);
442 
443  //The recipient must copy the senderNonce into the recipientNonce of the
444  //reply as a proof of liveliness
447  sizeof(SCEP_RECIPIENT_NONCE_OID), &attribute);
448  //Any error to report?
449  if(error)
450  return error;
451 
452  //The nonce must be a 16-byte binary data string
453  if(attribute.data.length != SCEP_NONCE_SIZE)
454  return ERROR_BAD_NONCE;
455 
456  //The original sender must verify that the recipientNonce of the reply
457  //matches the senderNonce it sent in the request. If the nonce does not
458  //match, then the message must be rejected (refer to RFC 8894,
459  //section 3.2.1.5)
460  if(osMemcmp(attribute.data.value, context->senderNonce, SCEP_NONCE_SIZE) != 0)
461  return ERROR_BAD_NONCE;
462 
463  //All response messages must include transaction status information, which
464  //is defined as a pkiStatus attribute (refer to RFC 8894, section 3.2.1.3)
467  sizeof(SCEP_PKI_STATUS_OID), &attribute);
468  //Any error to report?
469  if(error)
470  return error;
471 
472  //The attribute is encoded as a PrintableString
473  if(attribute.type != ASN1_TYPE_PRINTABLE_STRING)
474  return ERROR_INVALID_SYNTAX;
475 
476  //The attribute value is a numeric text string
477  error = x509ParseInt(attribute.data.value, attribute.data.length,
478  &pkiStatus);
479  //Any error to report?
480  if(error)
481  return error;
482 
483  //Debug message
484  scepDumpPkiStatus(pkiStatus);
485 
486  //Check PKI status
487  if(pkiStatus == SCEP_PKI_STATUS_SUCCESS)
488  {
489  //The data content type is just an octet string (refer to RFC 2315,
490  //section 8)
491  error = asn1ReadOctetString(signedData.contentInfo.content.value,
492  signedData.contentInfo.content.length, &tag);
493  //Any error to report?
494  if(error)
495  return error;
496 
497  //When the pkiStatus attribute is set to SUCCESS, the messageData for
498  //this message consists of a degenerate certificates-only CMS SignedData
499  //message
500  error = scepClientParsePkcsPkiEnvelope(context, messageType, tag.value,
501  tag.length);
502  //Any error to report?
503  if(error)
504  return error;
505  }
506  else if(pkiStatus == SCEP_PKI_STATUS_FAILURE)
507  {
508  //When the pkiStatus attribute is set to FAILURE, the reply must also
509  //contain a failInfo attribute set to the appropriate error condition
510  //describing the failure (refer to RFC 8894, section 3.3.2.2)
513  sizeof(SCEP_FAIL_INFO_OID), &attribute);
514  //Any error to report?
515  if(error)
516  return error;
517 
518  //The attribute is encoded as a PrintableString
519  if(attribute.type != ASN1_TYPE_PRINTABLE_STRING)
520  return ERROR_INVALID_SYNTAX;
521 
522  //The attribute value is a numeric text string
523  error = x509ParseInt(attribute.data.value, attribute.data.length,
524  &context->failInfo);
525  //Any error to report?
526  if(error)
527  return error;
528 
529  //Debug message
530  scepDumpFailInfo(context->failInfo);
531 
532  //The request is rejected
533  return ERROR_REQUEST_REJECTED;
534  }
535  else if(pkiStatus == SCEP_PKI_STATUS_PENDING)
536  {
537  //The Request pending for manual approval (refer to RFC 8894, section
538  //3.2.1.3)
539  return ERROR_REQUEST_PENDING;
540  }
541  else
542  {
543  //PKI status values not defined above must be treated as errors unless
544  //their use has been negotiated through GetCACaps (refer to RFC 8894,
545  //section 3.2.1.3)
546  return ERROR_INVALID_SYNTAX;
547  }
548 
549  //Successful processing
550  return NO_ERROR;
551 }
552 
553 
554 /**
555  * @brief Parse pkcsPKIEnvelope structure
556  * @param[in] context Pointer to the SCEP client context
557  * @param[in] messageType SCEP message type
558  * @param[in] data Pointer to the pkcsPKIEnvelope structure to parse
559  * @param[in] length Length of the pkcsPKIEnvelope structure
560  * @return Error code
561  **/
562 
564  uint_t messageType, const uint8_t *data, size_t length)
565 {
566  error_t error;
567  size_t n;
568  Pkcs7ContentInfo contentInfo;
569  Pkcs7EnvelopedData envelopedData;
570  X509CertInfo *certInfo;
571 
572  //Debug message
573  TRACE_DEBUG("pkcsPKIEnvelope (%" PRIuSIZE " bytes):\r\n", length);
575 
576  //The general syntax for content exchanged between entities associates a
577  //content type with content (refer to RFC 2315, section 7)
578  error = pkcs7ParseContentInfo(data, length, &n, &contentInfo);
579  //Any error to report?
580  if(error)
581  return error;
582 
583  //The information portion of a SCEP message is carried inside an
584  //EnvelopedData content type (refer to RFC 8894, section 3.2.2)
585  if(OID_COMP(contentInfo.contentType.value, contentInfo.contentType.length,
587  {
588  return ERROR_INVALID_TYPE;
589  }
590 
591  //Parse enveloped-data content
592  error = pkcs7ParseEnvelopedData(contentInfo.content.value,
593  contentInfo.content.length, &envelopedData);
594  //Any error to report?
595  if(error)
596  return error;
597 
598  //Allocate a memory buffer to store X.509 certificate info
599  certInfo = cryptoAllocMem(sizeof(X509CertInfo));
600 
601  //Successful memory allocation?
602  if(certInfo != NULL)
603  {
604  //If the key being certified allows encryption, then the CA's CertResp
605  //will use the same certificate's public key when encrypting the response
606  //(refer to RFC 8894, section 2.3)
607  error = x509ParseCertificate(context->cert, context->certLen, certInfo);
608 
609  //Check status code
610  if(!error)
611  {
612  //Decrypt enveloped-data content
613  error = pkcs7DecryptEnvelopedData(&envelopedData, certInfo,
614  &context->rsaPrivateKey, context->buffer, &n);
615  }
616 
617  //Release previously allocated memory
618  cryptoFreeMem(certInfo);
619  }
620  else
621  {
622  //Failed to allocate memory
623  error = ERROR_OUT_OF_MEMORY;
624  }
625 
626  //Any error to report?
627  if(error)
628  return error;
629 
630  //When a particular SCEP message carries data, this data is carried in the
631  //messageData (refer to RFC 8894, section 3)
632  return scepClientParseMessageData(context, messageType, context->buffer, n);
633 }
634 
635 
636 /**
637  * @brief Parse messageData
638  * @param[in] context Pointer to the SCEP client context
639  * @param[in] messageType SCEP message type
640  * @param[in] data Pointer to the pkcsPKIEnvelope structure to parse
641  * @param[in] length Length of the pkcsPKIEnvelope structure
642  * @return Error code
643  **/
644 
646  uint_t messageType, const uint8_t *data, size_t length)
647 {
648  error_t error;
649  size_t n;
650  Pkcs7ContentInfo contentInfo;
651  Pkcs7SignedData signedData;
652  Asn1Tag tag;
653 
654  //The CertRep is the response to certificate or CRL request
655  if(messageType != SCEP_MSG_TYPE_CERT_REP)
656  return ERROR_INVALID_TYPE;
657 
658  //Debug message
659  TRACE_DEBUG("messageData (%" PRIuSIZE " bytes):\r\n", length);
661 
662  //The general syntax for content exchanged between entities associates a
663  //content type with content (refer to RFC 2315, section 7)
664  error = pkcs7ParseContentInfo(data, length, &n, &contentInfo);
665  //Any error to report?
666  if(error)
667  return error;
668 
669  //The messageData for this type consists of a degenerate certificates-only CMS
670  //SignedData message (refer to RFC 8894, section 3.3.2)
671  if(OID_COMP(contentInfo.contentType.value, contentInfo.contentType.length,
672  PKCS7_SIGNED_DATA_OID) != 0)
673  {
674  return ERROR_INVALID_TYPE;
675  }
676 
677  //Parse signed-data content
678  error = pkcs7ParseSignedData(contentInfo.content.value,
679  contentInfo.content.length, &signedData);
680  //Any error to report?
681  if(error)
682  return error;
683 
684  //The messageData for this type consists of a degenerate certificates-only
685  //CMS SignedData message (refer to RFC 8894, section 3.3.2)
686  if(signedData.contentInfo.content.length != 0 ||
687  signedData.signerInfos.numSignerInfos != 0)
688  {
689  return ERROR_INVALID_SYNTAX;
690  }
691 
692  //Debug message
693  TRACE_DEBUG("certificates (%" PRIuSIZE " bytes):\r\n", context->certLen);
694  asn1DumpObject(context->cert, context->certLen, 0);
695 
696  //The reply must contain at least the issued certificate in the certificates
697  //field of the SignedData. The reply may contain additional certificates,
698  //but the issued certificate must be the leaf certificate (refer to RFC 8894,
699  //section 3.3.2.1)
700  if(signedData.certificates.raw.length == 0)
701  return ERROR_INVALID_SYNTAX;
702 
703  //Point to the first certificate
704  data = signedData.certificates.raw.value;
705  length = signedData.certificates.raw.length;
706 
707  //Loop through the certificate
708  while(length > 0)
709  {
710  //Parse certificate
711  error = asn1ReadSequence(data, length, &tag);
712  //Any error to report?
713  if(error)
714  return error;
715 
716  //Leaf certificate?
717  if(tag.totalLength == length)
718  break;
719 
720  //Next certificate
721  data += tag.totalLength;
722  length -= tag.totalLength;
723  }
724 
725  //Check the length of the issued certificate
728 
729  //Save the issued certificate
730  osMemcpy(context->cert, data, length);
731  context->certLen = length;
732 
733  //Sucessful processing
734  return NO_ERROR;
735 }
736 
737 #endif
error_t scepClientVerifyCaCert(ScepClientContext *context)
Verify CA certificate.
@ SCEP_MSG_TYPE_CERT_REP
CertRep.
Definition: scep_common.h:54
X.509 certificate parsing.
String manipulation helper functions.
void scepDumpMessageType(uint_t messageType)
Dump SCEP message type.
Definition: scep_debug.c:78
#define ScepClientContext
Definition: scep_client.h:165
Pkcs7Certificates certificates
Definition: pkcs7_common.h:355
#define HTTP_STATUS_CODE_2YZ(code)
Definition: http_common.h:44
OID (Object Identifier)
@ SCEP_CA_CAPS_POST_PKI_OPERATION
POSTPKIOperation.
Definition: scep_common.h:99
uint8_t p
Definition: ndp.h:300
char_t * strTrimWhitespace(char_t *s)
Removes all leading and trailing whitespace from a string.
Definition: str.c:78
Pkcs7AuthenticatedAttributes authenticatedAttributes
Definition: pkcs7_common.h:268
error_t scepClientParseMessageData(ScepClientContext *context, uint_t messageType, const uint8_t *data, size_t length)
Parse messageData.
error_t x509ParseCertificate(const uint8_t *data, size_t length, X509CertInfo *certInfo)
Parse a X.509 certificate.
uint8_t data[]
Definition: ethernet.h:224
Pkcs7ContentInfo contentInfo
Definition: pkcs7_common.h:354
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:999
#define osMemcmp(p1, p2, length)
Definition: os_port.h:156
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
Content information.
Definition: pkcs7_common.h:317
@ SCEP_PKI_STATUS_FAILURE
Failure.
Definition: scep_common.h:70
#define osStrcmp(s1, s2)
Definition: os_port.h:174
#define osStrlen(s)
Definition: os_port.h:168
X509OctetString data
Definition: pkcs7_common.h:228
error_t pkcs7ParseSignedData(const uint8_t *data, size_t length, Pkcs7SignedData *signedData)
Parse signed-data content.
Definition: pkcs7_parse.c:131
@ SCEP_PKI_STATUS_SUCCESS
Success.
Definition: scep_common.h:69
const uint8_t SCEP_PKI_STATUS_OID[10]
Definition: scep_common.c:44
size_t totalLength
Definition: asn1.h:111
error_t scepClientParsePkiMessage(ScepClientContext *context, const uint8_t *data, size_t length)
Parse PKI message.
size_t length
Definition: asn1.h:109
void scepDumpFailInfo(uint_t failInfo)
Dump failure reason.
Definition: scep_debug.c:119
@ SCEP_CA_CAPS_AES
AES.
Definition: scep_common.h:96
error_t asn1ReadOctetString(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an octet string from the input stream.
Definition: asn1.c:190
error_t scepClientParseCertResponse(ScepClientContext *context)
Parse CertRep response.
@ ERROR_UNEXPECTED_STATUS
Definition: error.h:284
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
PKCS #7 message parsing.
#define SCEP_CLIENT_BUFFER_SIZE
Definition: scep_client.h:104
X.509 certificate.
Definition: x509_common.h:1119
const uint8_t SCEP_RECIPIENT_NONCE_OID[10]
Definition: scep_common.c:50
error_t
Error codes.
Definition: error.h:43
Data logging functions for debugging purpose (SCEP)
error_t pkcs7FindSigner(const Pkcs7SignerInfos *signerInfos, const X509CertInfo *signerCertInfo, Pkcs7SignerInfo *signerInfo)
Search a list of per-signer informations for a given signer.
Signer information.
Definition: pkcs7_common.h:264
X509OctetString contentType
Definition: pkcs7_common.h:318
#define osStrtok_r(s, delim, last)
Definition: os_port.h:228
const uint8_t SCEP_TRANSACTION_ID_OID[10]
Definition: scep_common.c:52
@ ERROR_RESPONSE_TOO_LARGE
Definition: error.h:285
const uint8_t SCEP_MESSAGE_TYPE_OID[10]
Definition: scep_common.c:42
error_t scepClientParseGetCaCapsResponse(ScepClientContext *context)
Parse GetCACaps response.
@ SCEP_CA_CAPS_RENEWAL
Renewal.
Definition: scep_common.h:100
ASN.1 tag.
Definition: asn1.h:105
error_t scepClientParseGetCaCertResponse(ScepClientContext *context)
Parse GetCACert response.
error_t scepClientParseCaCert(ScepClientContext *context, X509CertInfo *certInfo)
Parse CA certificate.
#define osStrcasecmp(s1, s2)
Definition: os_port.h:186
@ SCEP_CA_CAPS_SHA1
SHA-1.
Definition: scep_common.h:101
error_t pkcs7VerifySignedData(const Pkcs7SignedData *signedData, const Pkcs7SignerInfo *signerInfo, const X509CertInfo *signerCertInfo)
Verify signature over signed-data content.
@ ERROR_INVALID_TYPE
Definition: error.h:115
@ ASN1_TYPE_PRINTABLE_STRING
Definition: asn1.h:86
uint8_t length
Definition: tcp.h:375
void scepDumpPkiStatus(uint_t pkiStatus)
Dump PKI status.
Definition: scep_debug.c:99
error_t pkcs7FindAttribute(const uint8_t *data, size_t length, const uint8_t *oid, size_t oidLen, Pkcs7Attribute *attribute)
Search a set of attributes for a given attribute type.
Definition: pkcs7_parse.c:1088
PKCS #7 message decryption.
@ SCEP_CA_CAPS_NONE
None.
Definition: scep_common.h:95
#define SCEP_CLIENT_MAX_CA_CERT_LEN
Definition: scep_client.h:146
Signed data content.
Definition: pkcs7_common.h:351
PKCS #7 signature verification.
SCEP client.
#define TRACE_DEBUG(...)
Definition: debug.h:119
char char_t
Definition: compiler_port.h:55
@ SCEP_CA_CAPS_DES3
DES3.
Definition: scep_common.h:97
error_t pkcs7ParseContentInfo(const uint8_t *data, size_t length, size_t *totalLength, Pkcs7ContentInfo *contentInfo)
Parse contentInfo structure.
Definition: pkcs7_parse.c:56
@ SCEP_CA_CAPS_SHA256
SHA-256.
Definition: scep_common.h:102
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
uint8_t n
#define SCEP_CLIENT_MAX_CERT_LEN
Definition: scep_client.h:139
error_t pkcs7DecryptEnvelopedData(const Pkcs7EnvelopedData *envelopedData, const X509CertInfo *recipientCertInfo, const void *recipientPrivateKey, uint8_t *plaintext, size_t *plaintextLen)
Decrypt enveloped-data content.
Definition: pkcs7_decrypt.c:57
X509OctetString content
Definition: pkcs7_common.h:319
#define cryptoFreeMem(p)
Definition: crypto.h:833
const uint8_t PKCS7_SIGNED_DATA_OID[9]
Definition: pkcs7_common.c:52
error_t x509ParseInt(const uint8_t *data, size_t length, uint_t *value)
Convert string to integer.
#define SCEP_NONCE_SIZE
Definition: scep_common.h:39
Pkcs7SignerInfos signerInfos
Definition: pkcs7_common.h:357
#define cryptoAllocMem(size)
Definition: crypto.h:828
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
X509OctetString raw
Definition: pkcs7_common.h:191
error_t scepClientParsePkcsPkiEnvelope(ScepClientContext *context, uint_t messageType, const uint8_t *data, size_t length)
Parse pkcsPKIEnvelope structure.
#define osStrncmp(s1, s2, length)
Definition: os_port.h:180
SCEP response parsing.
const uint8_t * value
Definition: x509_common.h:702
const uint8_t SCEP_FAIL_INFO_OID[10]
Definition: scep_common.c:46
@ ERROR_REQUEST_REJECTED
Definition: error.h:273
error_t pkcs7ParseEnvelopedData(const uint8_t *data, size_t length, Pkcs7EnvelopedData *envelopedData)
Parse enveloped-data content.
Definition: pkcs7_parse.c:224
const uint8_t PKCS7_ENVELOPED_DATA_OID[9]
Definition: pkcs7_common.c:54
@ SCEP_PKI_STATUS_PENDING
Pending.
Definition: scep_common.h:71
#define PRIuSIZE
unsigned int uint_t
Definition: compiler_port.h:57
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
@ ERROR_REQUEST_PENDING
Definition: error.h:310
Helper functions for SCEP client.
Enveloped data content.
Definition: pkcs7_common.h:366
@ ERROR_INVALID_RESPONSE
Definition: error.h:71
@ SCEP_CA_CAPS_SHA512
SHA-512.
Definition: scep_common.h:103
const uint8_t * value
Definition: asn1.h:110
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ SCEP_CA_CAPS_GET_NEXT_CA_CERT
GetNextCACert.
Definition: scep_common.h:98
ASN.1 (Abstract Syntax Notation One)
uint8_t token[]
Definition: coap_common.h:181
Attribute.
Definition: pkcs7_common.h:225
@ ERROR_BAD_NONCE
Definition: error.h:283