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.0
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"))
205  {
206  //Select NIST P-256 elliptic curve
207  crv = "P-256";
208  }
209  else if(!osStrcmp(params->name, "secp384r1"))
210  {
211  //Select NIST P-384 elliptic curve
212  crv = "P-384";
213  }
214  else if(!osStrcmp(params->name, "secp521r1"))
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"))
359  {
360  //The public key consists of 32 octets
361  n = 32;
362  }
363  else if(!osStrcmp(crv, "Ed448"))
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") || !osStrcmp(alg, "RS384") || !osStrcmp(alg, "RS512"))
584  {
585  const HashAlgo *hashAlgo;
586  uint8_t digest[SHA512_DIGEST_SIZE];
587 
588  //Select the relevant signature algorithm
589  if(!osStrcmp(alg, "RS256"))
590  {
591  //RSASSA-PKCS1-v1_5 algorithm with SHA-256
592  hashAlgo = SHA256_HASH_ALGO;
593  }
594  else if(!osStrcmp(alg, "RS384"))
595  {
596  //RSASSA-PKCS1-v1_5 algorithm with SHA-384
597  hashAlgo = SHA384_HASH_ALGO;
598  }
599  else if(!osStrcmp(alg, "RS512"))
600  {
601  //RSASSA-PKCS1-v1_5 algorithm with SHA-512
602  hashAlgo = SHA512_HASH_ALGO;
603  }
604  else
605  {
606  //Just for sanity
607  hashAlgo = NULL;
608  }
609 
610  //Valid hash algorithm?
611  if(hashAlgo != NULL)
612  {
613  //Digest the JWS signing input
614  error = hashAlgo->compute(input, inputLen, digest);
615  }
616  else
617  {
618  //Report an error
620  }
621 
622  //Check status code
623  if(!error)
624  {
625  //Generate RSA signature
626  error = rsassaPkcs1v15Sign(privateKey, hashAlgo, digest, output,
627  outputLen);
628  }
629  }
630  else
631 #endif
632 #if (ACME_CLIENT_ECDSA_SUPPORT == ENABLED)
633  //ECDSA algorithm?
634  if(!osStrcmp(alg, "ES256") || !osStrcmp(alg, "ES384") || !osStrcmp(alg, "ES512"))
635  {
636  size_t n;
637  const HashAlgo *hashAlgo;
638  const EcCurveInfo *curveInfo;
639  EcDomainParameters params;
640  EcdsaSignature signature;
641  uint8_t digest[SHA512_DIGEST_SIZE];
642 
643  //Initialize EC domain parameters
644  ecInitDomainParameters(&params);
645  //Initialize ECDSA signature
646  ecdsaInitSignature(&signature);
647 
648  //Select the relevant signature algorithm
649  if(!osStrcmp(alg, "ES256"))
650  {
651  //ECDSA algorithm using P-256 and SHA-256
652  curveInfo = SECP256R1_CURVE;
653  hashAlgo = SHA256_HASH_ALGO;
654  }
655  else if(!osStrcmp(alg, "ES384"))
656  {
657  //ECDSA algorithm using P-384 and SHA-384
658  curveInfo = SECP384R1_CURVE;
659  hashAlgo = SHA384_HASH_ALGO;
660  }
661  else if(!osStrcmp(alg, "ES512"))
662  {
663  //ECDSA algorithm using P-521 and SHA-512
664  curveInfo = SECP521R1_CURVE;
665  hashAlgo = SHA512_HASH_ALGO;
666  }
667  else
668  {
669  //Just for sanity
670  curveInfo = NULL;
671  hashAlgo = NULL;
672  }
673 
674  //Valid signature algorithm?
675  if(curveInfo != NULL && hashAlgo != NULL)
676  {
677  //Load EC domain parameters
678  error = ecLoadDomainParameters(&params, curveInfo);
679  }
680  else
681  {
682  //Report an error
684  }
685 
686  //Check status code
687  if(!error)
688  {
689  //Digest the JWS signing input
690  error = hashAlgo->compute(input, inputLen, digest);
691  }
692 
693  //Check status code
694  if(!error)
695  {
696  //Generate ECDSA signature (R, S)
697  error = ecdsaGenerateSignature(prngAlgo, prngContext, &params,
698  privateKey, digest, hashAlgo->digestSize, &signature);
699  }
700 
701  //Check status code
702  if(!error)
703  {
704  //Turn R and S into octet sequences in big-endian order, with each
705  //array being be 32 octets long. The octet sequence representations
706  //must not be shortened to omit any leading zero octets contained in
707  //the values (refer to RFC 7518, section 3.4)
708  n = mpiGetByteLength(&params.q);
709 
710  //Convert R to an octet string
711  error = mpiExport(&signature.r, (uint8_t *) output, n,
713  }
714 
715  //Check status code
716  if(!error)
717  {
718  //Convert S to an octet string
719  error = mpiExport(&signature.s, (uint8_t *) output + n, n,
721  }
722 
723  //Check status code
724  if(!error)
725  {
726  //Concatenate the two octet sequences in the order R and then S.
727  //The resulting 64-octet sequence is the JWS signature value
728  *outputLen = 2 * n;
729  }
730 
731  //Release previously allocated resources
732  ecFreeDomainParameters(&params);
733  ecdsaFreeSignature(&signature);
734  }
735  else
736 #endif
737 #if (ACME_CLIENT_ED25519_SUPPORT == ENABLED)
738  //Ed25519 algorithm?
739  if(!osStrcmp(alg, "EdDSA") && !osStrcmp(crv, "Ed25519"))
740  {
741  const EddsaPrivateKey *eddsaPrivateKey;
742  uint8_t d[ED25519_PRIVATE_KEY_LEN];
743 
744  //Point to the EdDSA private key
745  eddsaPrivateKey = (const EddsaPrivateKey *) privateKey;
746 
747  //Retrieve private key
748  error = mpiExport(&eddsaPrivateKey->d, d, ED25519_PRIVATE_KEY_LEN,
750 
751  //Check status code
752  if(!error)
753  {
754  //Generate Ed25519 signature (PureEdDSA mode)
755  error = ed25519GenerateSignature(d, NULL, input, inputLen,
756  NULL, 0, 0, output);
757  }
758 
759  //Length of the resulting EdDSA signature
760  *outputLen = ED25519_SIGNATURE_LEN;
761  }
762  else
763 #endif
764 #if (ACME_CLIENT_ED448_SUPPORT == ENABLED)
765  //Ed448 algorithm?
766  if(!osStrcmp(alg, "EdDSA") && !osStrcmp(crv, "Ed448"))
767  {
768  const EddsaPrivateKey *eddsaPrivateKey;
769  uint8_t d[ED448_PRIVATE_KEY_LEN];
770 
771  //Point to the EdDSA private key
772  eddsaPrivateKey = (const EddsaPrivateKey *) privateKey;
773 
774  //Retrieve private key
775  error = mpiExport(&eddsaPrivateKey->d, d, ED448_PRIVATE_KEY_LEN,
777 
778  //Check status code
779  if(!error)
780  {
781  //Generate Ed448 signature (PureEdDSA mode)
782  error = ed448GenerateSignature(d, NULL, input, inputLen,
783  NULL, 0, 0, output);
784  }
785 
786  //Length of the resulting EdDSA signature
787  *outputLen = ED448_SIGNATURE_LEN;
788  }
789  else
790 #endif
791  //Unknown algorithm?
792  {
793  //Report an error
795  }
796 
797  //Return status code
798  return error;
799 }
800 
801 #endif
ACME client (Automatic Certificate Management Environment)
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.
error_t jwkExportRsaPublicKey(const RsaPublicKey *publicKey, char_t *buffer, size_t *written, bool_t sort)
Export an RSA public key to JWK format.
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.
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.
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.
JOSE (JSON Object Signing and Encryption)
void base64urlEncode(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
Base64url encoding algorithm.
Definition: base64url.c:72
Base64url encoding scheme.
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
#define PRIuSIZE
char char_t
Definition: compiler_port.h:48
int bool_t
Definition: compiler_port.h:53
#define PrngAlgo
Definition: crypto.h:917
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
uint8_t n
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:72
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:51
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:90
#define SECP521R1_CURVE
Definition: ec_curves.h:242
#define SECP256R1_CURVE
Definition: ec_curves.h:240
#define SECP384R1_CURVE
Definition: ec_curves.h:241
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:82
__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
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:69
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
#define ED25519_SIGNATURE_LEN
Definition: ed25519.h:44
#define ED25519_PRIVATE_KEY_LEN
Definition: ed25519.h:40
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 ED448_PRIVATE_KEY_LEN
Definition: ed448.h:40
#define ED448_SIGNATURE_LEN
Definition: ed448.h:44
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ ERROR_INVALID_SIGNATURE_ALGO
Definition: error.h:134
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
uint8_t payload[]
Definition: ipv6.h:277
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:709
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
@ MPI_FORMAT_LITTLE_ENDIAN
Definition: mpi.h:70
uint8_t s
Definition: ndp.h:345
uint8_t p
Definition: ndp.h:300
#define osStrcmp(s1, s2)
Definition: os_port.h:171
#define osStrlen(s)
Definition: os_port.h:165
#define osStrcpy(s1, s2)
Definition: os_port.h:207
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 SHA256_HASH_ALGO
Definition: sha256.h:49
#define SHA384_HASH_ALGO
Definition: sha384.h:45
#define SHA512_HASH_ALGO
Definition: sha512.h:49
#define SHA512_DIGEST_SIZE
Definition: sha512.h:45
Elliptic curve parameters.
Definition: ec_curves.h:295
EC domain parameters.
Definition: ec.h:76
Mpi p
Prime.
Definition: ec.h:79
const char_t * name
Curve name.
Definition: ec.h:77
Mpi q
Order of the point G.
Definition: ec.h:83
Mpi y
y-coordinate
Definition: ec.h:66
Mpi x
x-coordinate
Definition: ec.h:65
EC public key.
Definition: ec.h:94
EcPoint q
Public key.
Definition: ec.h:95
ECDSA signature.
Definition: ecdsa.h:49
EdDSA private key.
Definition: eddsa.h:59
Mpi d
Private key.
Definition: eddsa.h:60
EdDSA public key.
Definition: eddsa.h:49
Mpi q
Public key.
Definition: eddsa.h:50
Common interface for hash algorithms.
Definition: crypto.h:1014
HashAlgoCompute compute
Definition: crypto.h:1023
size_t digestSize
Definition: crypto.h:1020
RSA public key.
Definition: rsa.h:57
Mpi e
Public exponent.
Definition: rsa.h:59
Mpi n
Modulus.
Definition: rsa.h:58
uint8_t flags
Definition: tcp.h:351