acme_client_jose.c
Go to the documentation of this file.
1 /**
2  * @file acme_client_jose.c
3  * @brief JOSE (JSON Object Signing and Encryption)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2019-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneACME 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.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL ACME_TRACE_LEVEL
33 
34 //Dependencies
35 #include "acme/acme_client.h"
36 #include "acme/acme_client_jose.h"
37 #include "encoding/base64url.h"
38 #include "jansson.h"
39 #include "jansson_private.h"
40 #include "debug.h"
41 
42 //Check TCP/IP stack configuration
43 #if (ACME_CLIENT_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief Export an RSA public key to JWK format
48  * @param[in] publicKey RSA public key
49  * @param[out] buffer Output buffer where to store the JSON representation
50  * @param[out] written Length of the resulting JSON representation
51  * @param[in] sort Sort members of the JWK representation in lexicographic order
52  * @return Error code
53  **/
54 
56  size_t *written, bool_t sort)
57 {
58  error_t error;
59  int_t ret;
60  size_t n;
61  uint_t flags;
62  char_t *s;
63  json_t *rootObj;
64 
65  //Initialize status code
66  error = NO_ERROR;
67 
68  //Initialize variables
69  ret = 0;
70  s = NULL;
71 
72  //Initialize JSON object
73  rootObj = json_object();
74 
75  //Start of exception handling block
76  do
77  {
78  //The "kty" (key type) parameter identifies the cryptographic algorithm
79  //family used with the key (refer to RFC 7517, section 4.1)
80  ret = json_object_set_new(rootObj, "kty", json_string("RSA"));
81  //Any error to report?
82  if(ret != 0)
83  break;
84 
85  //The octet sequence must utilize the minimum number of octets to
86  //represent the RSA modulus (refer to RFC 7518, section 6.3.1.1)
87  n = mpiGetByteLength(&publicKey->n);
88 
89  //Convert the RSA modulus to an octet string
90  error = mpiExport(&publicKey->n, (uint8_t *) buffer, n,
92  //Any error to report?
93  if(error)
94  break;
95 
96  //Integers are represented using the base64url encoding of their
97  //big-endian representations
98  base64urlEncode(buffer, n, buffer, &n);
99 
100  //Format "n" parameter
101  ret = json_object_set_new(rootObj, "n", json_string(buffer));
102  //Any error to report?
103  if(ret != 0)
104  break;
105 
106  //Retrieve the length of the RSA public exponent
107  n = mpiGetByteLength(&publicKey->e);
108 
109  //Convert the RSA public exponent to an octet string
110  error = mpiExport(&publicKey->e, (uint8_t *) buffer, n,
112  //Any error to report?
113  if(error)
114  break;
115 
116  //Integers are represented using the base64url encoding of their
117  //big-endian representations
118  base64urlEncode(buffer, n, buffer, &n);
119 
120  //Format "e" parameter
121  ret = json_object_set_new(rootObj, "e", json_string(buffer));
122  //Any error to report?
123  if(ret != 0)
124  break;
125 
126  //If this sort parameter is set, all the keys of the JWK representation
127  //are sorted in lexicographic order
128  flags = sort ? (JSON_COMPACT | JSON_SORT_KEYS) : JSON_COMPACT;
129 
130  //Generate the JSON representation of the JWK object
131  s = json_dumps(rootObj, flags);
132 
133  //End of exception handling block
134  } while(0);
135 
136  //Valid JSON representation?
137  if(s != NULL)
138  {
139  //Copy JSON string
140  osStrcpy(buffer, s);
141  //Total number of bytes that have been written
142  *written = osStrlen(s);
143 
144  //Release JSON string
145  jsonp_free(s);
146  }
147  else
148  {
149  //Report an error
150  error = ERROR_FAILURE;
151  }
152 
153  //Release JSON object
154  json_decref(rootObj);
155 
156  //Return status code
157  return error;
158 }
159 
160 
161 /**
162  * @brief Export an EC public key to JWK format
163  * @param[in] params EC domain parameters
164  * @param[in] publicKey EC public key
165  * @param[out] buffer Output buffer where to store the JSON representation
166  * @param[out] written Length of the resulting JSON representation
167  * @param[in] sort Sort members of the JWK representation in lexicographic order
168  * @return Error code
169  **/
170 
172  const EcPublicKey *publicKey, char_t *buffer, size_t *written, bool_t sort)
173 {
174  error_t error;
175  int_t ret;
176  size_t n;
177  uint_t flags;
178  char_t *s;
179  const char_t *crv;
180  json_t *rootObj;
181 
182  //Initialize status code
183  error = NO_ERROR;
184 
185  //Initialize variables
186  ret = 0;
187  s = NULL;
188 
189  //Initialize JSON object
190  rootObj = json_object();
191 
192  //Start of exception handling block
193  do
194  {
195  //The "kty" (key type) parameter identifies the cryptographic algorithm
196  //family used with the key (refer to RFC 7517, section 4.1)
197  ret = json_object_set_new(rootObj, "kty", json_string("EC"));
198  //Any error to report?
199  if(ret != 0)
200  break;
201 
202  //The "crv" (curve) parameter identifies the cryptographic curve used
203  //with the key (refer to RFC 7518, section 6.2.1.1)
204  if(osStrcmp(params->name, "secp256r1") == 0)
205  {
206  //Select NIST P-256 elliptic curve
207  crv = "P-256";
208  }
209  else if(osStrcmp(params->name, "secp384r1") == 0)
210  {
211  //Select NIST P-384 elliptic curve
212  crv = "P-384";
213  }
214  else if(osStrcmp(params->name, "secp521r1") == 0)
215  {
216  //Select NIST P-521 elliptic curve
217  crv = "P-521";
218  }
219  else
220  {
221  //Report an error
222  error = ERROR_WRONG_IDENTIFIER;
223  break;
224  }
225 
226  //Format "crv" parameter
227  ret |= json_object_set_new(rootObj, "crv", json_string(crv));
228  //Any error to report?
229  if(ret != 0)
230  break;
231 
232  //The length of the "x" octet string must be the full size of the
233  //x-coordinate for the curve specified in the "crv" parameter (refer
234  //to RFC 7518, section 6.2.1.2)
235  n = mpiGetByteLength(&params->p);
236 
237  //Convert the x-coordinate to an octet string
238  error = mpiExport(&publicKey->q.x, (uint8_t *) buffer, n,
240  //Any error to report?
241  if(error)
242  break;
243 
244  //Integers are represented using the base64url encoding of their
245  //big-endian representations
246  base64urlEncode(buffer, n, buffer, &n);
247 
248  //Format "x" parameter
249  ret = json_object_set_new(rootObj, "x", json_string(buffer));
250  //Any error to report?
251  if(ret != 0)
252  break;
253 
254  //The length of the "y" octet string must be the full size of the
255  //y-coordinate for the curve specified in the "crv" parameter (refer
256  //to RFC 7518, section 6.2.1.3)
257  n = mpiGetByteLength(&params->p);
258 
259  //Convert the y-coordinate to an octet string
260  error = mpiExport(&publicKey->q.y, (uint8_t *) buffer, n,
262  //Any error to report?
263  if(error)
264  break;
265 
266  //Integers are represented using the base64url encoding of their
267  //big-endian representations
268  base64urlEncode(buffer, n, buffer, &n);
269 
270  //Format "y" parameter
271  ret = json_object_set_new(rootObj, "y", json_string(buffer));
272  //Any error to report?
273  if(ret != 0)
274  break;
275 
276  //If this sort parameter is set, all the keys of the JWK representation
277  //are sorted in lexicographic order
278  flags = sort ? (JSON_COMPACT | JSON_SORT_KEYS) : JSON_COMPACT;
279 
280  //Generate the JSON representation of the JWK object
281  s = json_dumps(rootObj, flags);
282 
283  //End of exception handling block
284  } while(0);
285 
286  //Valid JSON representation?
287  if(s != NULL)
288  {
289  //Copy JSON string
290  osStrcpy(buffer, s);
291  //Total number of bytes that have been written
292  *written = osStrlen(s);
293 
294  //Release JSON string
295  jsonp_free(s);
296  }
297  else
298  {
299  //Report an error
300  error = ERROR_FAILURE;
301  }
302 
303  //Release JSON object
304  json_decref(rootObj);
305 
306  //Return status code
307  return error;
308 }
309 
310 
311 /**
312  * @brief Export an EdDSA public key to JWK format
313  * @param[in] crv Subtype of the key
314  * @param[in] publicKey EdDSA public key
315  * @param[out] buffer Output buffer where to store the JSON representation
316  * @param[out] written Length of the resulting JSON representation
317  * @param[in] sort Sort members of the JWK representation in lexicographic order
318  * @return Error code
319  **/
320 
322  const EddsaPublicKey *publicKey, char_t *buffer, size_t *written,
323  bool_t sort)
324 {
325  error_t error;
326  int_t ret;
327  size_t n;
328  uint_t flags;
329  char_t *s;
330  json_t *rootObj;
331 
332  //Initialize status code
333  error = NO_ERROR;
334 
335  //Initialize variables
336  ret = 0;
337  s = NULL;
338 
339  //Initialize JSON object
340  rootObj = json_object();
341 
342  //Start of exception handling block
343  do
344  {
345  //The parameter "kty" must be "OKP" (refer to RFC 8037, section 2)
346  ret = json_object_set_new(rootObj, "kty", json_string("OKP"));
347  //Any error to report?
348  if(ret != 0)
349  break;
350 
351  //The parameter "crv" must be present and contain the subtype of the key
352  ret |= json_object_set_new(rootObj, "crv", json_string(crv));
353  //Any error to report?
354  if(ret != 0)
355  break;
356 
357  //Retrieve the length of the public key
358  if(osStrcmp(crv, "Ed25519") == 0)
359  {
360  //The public key consists of 32 octets
361  n = 32;
362  }
363  else if(osStrcmp(crv, "Ed448") == 0)
364  {
365  //The public key consists of 57 octets
366  n = 57;
367  }
368  else
369  {
370  //Report an error
371  error = ERROR_WRONG_IDENTIFIER;
372  break;
373  }
374 
375  //Convert the public key to an octet string
376  error = mpiExport(&publicKey->q, (uint8_t *) buffer, n,
378  //Any error to report?
379  if(error)
380  break;
381 
382  //Integers are represented using the base64url encoding of their
383  //big-endian representations
384  base64urlEncode(buffer, n, buffer, &n);
385 
386  //Format "x" parameter
387  ret = json_object_set_new(rootObj, "x", json_string(buffer));
388  //Any error to report?
389  if(ret != 0)
390  break;
391 
392  //If this sort parameter is set, all the keys of the JWK representation
393  //are sorted in lexicographic order
394  flags = sort ? (JSON_COMPACT | JSON_SORT_KEYS) : JSON_COMPACT;
395 
396  //Generate the JSON representation of the JWK object
397  s = json_dumps(rootObj, flags);
398 
399  //End of exception handling block
400  } while(0);
401 
402  //Valid JSON representation?
403  if(s != NULL)
404  {
405  //Copy JSON string
406  osStrcpy(buffer, s);
407  //Total number of bytes that have been written
408  *written = osStrlen(s);
409 
410  //Release JSON string
411  jsonp_free(s);
412  }
413  else
414  {
415  //Report an error
416  error = ERROR_FAILURE;
417  }
418 
419  //Release JSON object
420  json_decref(rootObj);
421 
422  //Return status code
423  return error;
424 }
425 
426 
427 /**
428  * @brief Create a JSON Web Signature
429  * @param[in] prngAlgo PRNG algorithm
430  * @param[in] prngContext Pointer to the PRNG context
431  * @param[in] protected Pointer to the JWS protected header
432  * @param[in] payload Pointer to the JWS payload
433  * @param[in] alg Cryptographic algorithm used to secure the JWS
434  * @param[in] crv Subtype of the key
435  * @param[in] privateKey Pointer to the signer's private key
436  * @param[out] buffer JSON structure representing the digitally signed
437  * or MACed message
438  * @param[out] written Length of the resulting JSON structure
439  * @return Error code
440  **/
441 
442 error_t jwsCreate(const PrngAlgo *prngAlgo, void *prngContext,
443  const char_t *protected, const char_t *payload, const char_t *alg,
444  const char_t *crv, const void *privateKey, char_t *buffer, size_t *written)
445 {
446  error_t error;
447  int_t ret;
448  size_t n;
449  char_t *p;
450  char_t *s;
451  json_t *rootObj;
452 
453  //Debug message
454  TRACE_DEBUG("JWS protected header (%" PRIuSIZE " bytes):\r\n", osStrlen(protected));
455  TRACE_DEBUG("%s\r\n\r\n", protected);
456  TRACE_DEBUG("JWS payload (%" PRIuSIZE " bytes):\r\n", osStrlen(payload));
457  TRACE_DEBUG("%s\r\n\r\n", payload);
458 
459  //Initialize status code
460  error = NO_ERROR;
461 
462  //Initialize variables
463  ret = 0;
464  s = NULL;
465 
466  //Initialize JSON object
467  rootObj = json_object();
468 
469  //Start of exception handling block
470  do
471  {
472  //Point to the beginning of the buffer
473  p = buffer;
474 
475  //Encode the JWS protected header using Base64url
476  base64urlEncode(protected, osStrlen(protected), p, &n);
477 
478  //The "protected" member must be present and contain the value of the
479  //Base64url-encoded JWS protected header (refer to RFC 7515, section 7.2.1)
480  ret = json_object_set_new(rootObj, "protected", json_string(p));
481  //Any error to report?
482  if(ret != 0)
483  break;
484 
485  //Advance write pointer
486  p += n;
487 
488  //Insert a '.' character between the Base64url-encoded JWS protected
489  //header and JWS payload
490  *(p++) = '.';
491 
492  //Encode the JWS payload value using Base64url
494 
495  //The "payload" member must be present and contain the value of the
496  //Base64url-encoded JWS payload (refer to RFC 7515, section 7.2.1)
497  ret = json_object_set_new(rootObj, "payload", json_string(p));
498  //Any error to report?
499  if(ret != 0)
500  break;
501 
502  //Advance write pointer
503  p += n;
504  //Compute the length of the JWS signing input
505  n = p - buffer;
506 
507  //Compute the JWS Signature in the manner defined for the particular
508  //algorithm being used over the JWS signing input (refer to RFC 7515,
509  //section 5.1)
510  error = jwsGenerateSignature(prngAlgo, prngContext, alg, crv,
511  privateKey, buffer, n, (uint8_t *) buffer, &n);
512  //Any error to report?
513  if(error)
514  break;
515 
516  //Encode the JWS signature using Base64url
517  base64urlEncode(buffer, n, buffer, &n);
518 
519  //The "signature" member must be present and contain the value of the
520  //Base64url-encoded JWS Signature (refer to RFC 7515, section 7.2.1)
521  ret = json_object_set_new(rootObj, "signature", json_string(buffer));
522  //Any error to report?
523  if(ret != 0)
524  break;
525 
526  //Generate the JSON representation of the JWS object
527  s = json_dumps(rootObj, JSON_COMPACT);
528 
529  //End of exception handling block
530  } while(0);
531 
532  //Valid JSON representation?
533  if(s != NULL)
534  {
535  //Debug message
536  TRACE_DEBUG("JWS (%" PRIuSIZE " bytes):\r\n", osStrlen(s));
537  TRACE_DEBUG("%s\r\n\r\n", s);
538 
539  //Copy JSON string
540  osStrcpy(buffer, s);
541  //Total number of bytes that have been written
542  *written = osStrlen(s);
543 
544  //Release JSON string
545  jsonp_free(s);
546  }
547  else
548  {
549  //Report an error
550  error = ERROR_FAILURE;
551  }
552 
553  //Release JSON object
554  json_decref(rootObj);
555 
556  //Return status code
557  return error;
558 }
559 
560 
561 /**
562  * @brief Compute JWS signature using the specified algorithm
563  * @param[in] prngAlgo PRNG algorithm
564  * @param[in] prngContext Pointer to the PRNG context
565  * @param[in] alg Cryptographic algorithm used to secure the JWS
566  * @param[in] crv Subtype of the key
567  * @param[in] privateKey Pointer to the signer's private key
568  * @param[in] input Pointer to the JWS signing input
569  * @param[in] inputLen Length of the JWS signing input
570  * @param[out] output Buffer where to store the JWS signature
571  * @param[out] outputLen Length of the JWS signature
572  * @return Error code
573  **/
574 
575 error_t jwsGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
576  const char_t *alg, const char_t *crv, const void *privateKey,
577  const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen)
578 {
579  error_t error;
580 
581 #if (ACME_CLIENT_RSA_SUPPORT == ENABLED)
582  //RSASSA-PKCS1-v1_5 algorithm?
583  if(osStrcmp(alg, "RS256") == 0 || osStrcmp(alg, "RS384") == 0 ||
584  osStrcmp(alg, "RS512") == 0)
585  {
586  const HashAlgo *hashAlgo;
587  uint8_t digest[SHA512_DIGEST_SIZE];
588 
589  //Select the relevant signature algorithm
590  if(osStrcmp(alg, "RS256") == 0)
591  {
592  //RSASSA-PKCS1-v1_5 algorithm with SHA-256
593  hashAlgo = SHA256_HASH_ALGO;
594  }
595  else if(osStrcmp(alg, "RS384") == 0)
596  {
597  //RSASSA-PKCS1-v1_5 algorithm with SHA-384
598  hashAlgo = SHA384_HASH_ALGO;
599  }
600  else if(osStrcmp(alg, "RS512") == 0)
601  {
602  //RSASSA-PKCS1-v1_5 algorithm with SHA-512
603  hashAlgo = SHA512_HASH_ALGO;
604  }
605  else
606  {
607  //Just for sanity
608  hashAlgo = NULL;
609  }
610 
611  //Valid hash algorithm?
612  if(hashAlgo != NULL)
613  {
614  //Digest the JWS signing input
615  error = hashAlgo->compute(input, inputLen, digest);
616  }
617  else
618  {
619  //Report an error
621  }
622 
623  //Check status code
624  if(!error)
625  {
626  //Generate RSA signature
627  error = rsassaPkcs1v15Sign(privateKey, hashAlgo, digest, output,
628  outputLen);
629  }
630  }
631  else
632 #endif
633 #if (ACME_CLIENT_ECDSA_SUPPORT == ENABLED)
634  //ECDSA algorithm?
635  if(osStrcmp(alg, "ES256") == 0 || osStrcmp(alg, "ES384") == 0 ||
636  osStrcmp(alg, "ES512") == 0)
637  {
638  size_t n;
639  const HashAlgo *hashAlgo;
640  const EcCurveInfo *curveInfo;
641  EcDomainParameters params;
642  EcdsaSignature signature;
643  uint8_t digest[SHA512_DIGEST_SIZE];
644 
645  //Initialize EC domain parameters
646  ecInitDomainParameters(&params);
647  //Initialize ECDSA signature
648  ecdsaInitSignature(&signature);
649 
650  //Select the relevant signature algorithm
651  if(osStrcmp(alg, "ES256") == 0)
652  {
653  //ECDSA algorithm using P-256 and SHA-256
654  curveInfo = SECP256R1_CURVE;
655  hashAlgo = SHA256_HASH_ALGO;
656  }
657  else if(osStrcmp(alg, "ES384") == 0)
658  {
659  //ECDSA algorithm using P-384 and SHA-384
660  curveInfo = SECP384R1_CURVE;
661  hashAlgo = SHA384_HASH_ALGO;
662  }
663  else if(osStrcmp(alg, "ES512") == 0)
664  {
665  //ECDSA algorithm using P-521 and SHA-512
666  curveInfo = SECP521R1_CURVE;
667  hashAlgo = SHA512_HASH_ALGO;
668  }
669  else
670  {
671  //Just for sanity
672  curveInfo = NULL;
673  hashAlgo = NULL;
674  }
675 
676  //Valid signature algorithm?
677  if(curveInfo != NULL && hashAlgo != NULL)
678  {
679  //Load EC domain parameters
680  error = ecLoadDomainParameters(&params, curveInfo);
681  }
682  else
683  {
684  //Report an error
686  }
687 
688  //Check status code
689  if(!error)
690  {
691  //Digest the JWS signing input
692  error = hashAlgo->compute(input, inputLen, digest);
693  }
694 
695  //Check status code
696  if(!error)
697  {
698  //Generate ECDSA signature (R, S)
699  error = ecdsaGenerateSignature(prngAlgo, prngContext, &params,
700  privateKey, digest, hashAlgo->digestSize, &signature);
701  }
702 
703  //Check status code
704  if(!error)
705  {
706  //Turn R and S into octet sequences in big-endian order, with each
707  //array being be 32 octets long. The octet sequence representations
708  //must not be shortened to omit any leading zero octets contained in
709  //the values (refer to RFC 7518, section 3.4)
710  n = mpiGetByteLength(&params.q);
711 
712  //Convert R to an octet string
713  error = mpiExport(&signature.r, (uint8_t *) output, n,
715  }
716 
717  //Check status code
718  if(!error)
719  {
720  //Convert S to an octet string
721  error = mpiExport(&signature.s, (uint8_t *) output + n, n,
723  }
724 
725  //Check status code
726  if(!error)
727  {
728  //Concatenate the two octet sequences in the order R and then S.
729  //The resulting 64-octet sequence is the JWS signature value
730  *outputLen = 2 * n;
731  }
732 
733  //Release previously allocated resources
734  ecFreeDomainParameters(&params);
735  ecdsaFreeSignature(&signature);
736  }
737  else
738 #endif
739 #if (ACME_CLIENT_ED25519_SUPPORT == ENABLED)
740  //Ed25519 algorithm?
741  if(osStrcmp(alg, "EdDSA") == 0 && osStrcmp(crv, "Ed25519") == 0)
742  {
743  const EddsaPrivateKey *eddsaPrivateKey;
744  uint8_t d[ED25519_PRIVATE_KEY_LEN];
745 
746  //Point to the EdDSA private key
747  eddsaPrivateKey = (const EddsaPrivateKey *) privateKey;
748 
749  //Retrieve private key
750  error = mpiExport(&eddsaPrivateKey->d, d, ED25519_PRIVATE_KEY_LEN,
752 
753  //Check status code
754  if(!error)
755  {
756  //Generate Ed25519 signature (PureEdDSA mode)
757  error = ed25519GenerateSignature(d, NULL, input, inputLen,
758  NULL, 0, 0, output);
759  }
760 
761  //Length of the resulting EdDSA signature
762  *outputLen = ED25519_SIGNATURE_LEN;
763  }
764  else
765 #endif
766 #if (ACME_CLIENT_ED448_SUPPORT == ENABLED)
767  //Ed448 algorithm?
768  if(osStrcmp(alg, "EdDSA") == 0 && osStrcmp(crv, "Ed448") == 0)
769  {
770  const EddsaPrivateKey *eddsaPrivateKey;
771  uint8_t d[ED448_PRIVATE_KEY_LEN];
772 
773  //Point to the EdDSA private key
774  eddsaPrivateKey = (const EddsaPrivateKey *) privateKey;
775 
776  //Retrieve private key
777  error = mpiExport(&eddsaPrivateKey->d, d, ED448_PRIVATE_KEY_LEN,
779 
780  //Check status code
781  if(!error)
782  {
783  //Generate Ed448 signature (PureEdDSA mode)
784  error = ed448GenerateSignature(d, NULL, input, inputLen,
785  NULL, 0, 0, output);
786  }
787 
788  //Length of the resulting EdDSA signature
789  *outputLen = ED448_SIGNATURE_LEN;
790  }
791  else
792 #endif
793  //Unknown algorithm?
794  {
795  //Report an error
797  }
798 
799  //Return status code
800  return error;
801 }
802 
803 #endif
ECDSA signature.
Definition: ecdsa.h:49
#define SHA256_HASH_ALGO
Definition: sha256.h:49
int bool_t
Definition: compiler_port.h:53
Mpi p
Prime.
Definition: ec.h:79
#define SECP521R1_CURVE
Definition: ec_curves.h:249
#define SHA512_HASH_ALGO
Definition: sha512.h:49
signed int int_t
Definition: compiler_port.h:49
#define PrngAlgo
Definition: crypto.h:938
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:51
#define SECP384R1_CURVE
Definition: ec_curves.h:248
error_t jwkExportRsaPublicKey(const RsaPublicKey *publicKey, char_t *buffer, size_t *written, bool_t sort)
Export an RSA public key to JWK format.
uint8_t p
Definition: ndp.h:300
#define SECP256R1_CURVE
Definition: ec_curves.h:247
size_t digestSize
Definition: crypto.h:1052
#define ED448_SIGNATURE_LEN
Definition: ed448.h:44
#define osStrcmp(s1, s2)
Definition: os_port.h:171
#define ED25519_SIGNATURE_LEN
Definition: ed25519.h:44
Mpi e
Public exponent.
Definition: rsa.h:59
#define osStrlen(s)
Definition: os_port.h:165
Mpi y
y-coordinate
Definition: ec.h:66
EC domain parameters.
Definition: ec.h:76
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:72
JOSE (JSON Object Signing and Encryption)
#define ED25519_PRIVATE_KEY_LEN
Definition: ed25519.h:40
Mpi n
Modulus.
Definition: rsa.h:58
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:82
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:90
Elliptic curve parameters.
Definition: ec_curves.h:302
error_t ed25519GenerateSignature(const uint8_t *privateKey, const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed25519.c:236
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:709
__weak_func error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
Definition: ecdsa.c:397
@ MPI_FORMAT_LITTLE_ENDIAN
Definition: mpi.h:70
error_t
Error codes.
Definition: error.h:43
HashAlgoCompute compute
Definition: crypto.h:1055
void base64urlEncode(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
Base64url encoding algorithm.
Definition: base64url.c:72
Mpi q
Public key.
Definition: eddsa.h:50
EdDSA public key.
Definition: eddsa.h:49
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
RSA public key.
Definition: rsa.h:57
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:69
Mpi x
x-coordinate
Definition: ec.h:65
Base64url encoding scheme.
const char_t * name
Curve name.
Definition: ec.h:77
error_t jwkExportEddsaPublicKey(const char_t *crv, const EddsaPublicKey *publicKey, char_t *buffer, size_t *written, bool_t sort)
Export an EdDSA public key to JWK format.
EdDSA private key.
Definition: eddsa.h:59
#define ED448_PRIVATE_KEY_LEN
Definition: ed448.h:40
EC public key.
Definition: ec.h:94
#define SHA384_HASH_ALGO
Definition: sha384.h:45
uint8_t flags
Definition: tcp.h:351
#define TRACE_DEBUG(...)
Definition: debug.h:107
char char_t
Definition: compiler_port.h:48
@ ERROR_INVALID_SIGNATURE_ALGO
Definition: error.h:134
Mpi d
Private key.
Definition: eddsa.h:60
error_t jwsCreate(const PrngAlgo *prngAlgo, void *prngContext, const char_t *protected, const char_t *payload, const char_t *alg, const char_t *crv, const void *privateKey, char_t *buffer, size_t *written)
Create a JSON Web Signature.
uint8_t n
uint8_t payload[]
Definition: ipv6.h:286
error_t jwsGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const char_t *alg, const char_t *crv, const void *privateKey, const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen)
Compute JWS signature using the specified algorithm.
EcPoint q
Public key.
Definition: ec.h:95
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
uint8_t s
Definition: igmp_common.h:234
error_t jwkExportEcPublicKey(const EcDomainParameters *params, const EcPublicKey *publicKey, char_t *buffer, size_t *written, bool_t sort)
Export an EC public key to JWK format.
Common interface for hash algorithms.
Definition: crypto.h:1046
error_t rsassaPkcs1v15Sign(const RsaPrivateKey *key, const HashAlgo *hash, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PKCS1-v1_5 signature generation operation.
Definition: rsa.c:705
#define PRIuSIZE
unsigned int uint_t
Definition: compiler_port.h:50
#define osStrcpy(s1, s2)
Definition: os_port.h:207
ACME client (Automatic Certificate Management Environment)
error_t ed448GenerateSignature(const uint8_t *privateKey, const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed448.c:223
#define SHA512_DIGEST_SIZE
Definition: sha512.h:45
Mpi q
Order of the point G.
Definition: ec.h:83
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195