ssh_cert_parse.c
Go to the documentation of this file.
1 /**
2  * @file ssh_cert_parse.c
3  * @brief SSH certificate parsing
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2019-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSH 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 SSH_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ssh/ssh.h"
36 #include "ssh/ssh_cert_parse.h"
37 #include "ssh/ssh_misc.h"
38 #include "debug.h"
39 
40 //Check SSH stack configuration
41 #if (SSH_SUPPORT == ENABLED && SSH_CERT_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Parse SSH certificate
46  * @param[in] data Pointer to the certificate
47  * @param[in] length Length of the certificate, in bytes
48  * @param[out] cert Information resulting from the parsing process
49  * @return Error code
50  **/
51 
52 error_t sshParseCertificate(const uint8_t *data, size_t length,
53  SshCertificate *cert)
54 {
55  error_t error;
56  size_t n;
57 
58  //Clear the certificate information structure
59  osMemset(cert, 0, sizeof(SshCertificate));
60 
61  //Decode key format identifier
62  error = sshParseString(data, length, &cert->keyFormatId);
63  //Any error to report?
64  if(error)
65  return error;
66 
67  //Point to the next field
68  data += sizeof(uint32_t) + cert->keyFormatId.length;
69  length -= sizeof(uint32_t) + cert->keyFormatId.length;
70 
71  //Parse 'nonce' field
72  error = sshParseBinaryString(data, length, &cert->nonce);
73  //Any error to report?
74  if(error)
75  return error;
76 
77  //Point to the next field
78  data += sizeof(uint32_t) + cert->nonce.length;
79  length -= sizeof(uint32_t) + cert->nonce.length;
80 
81 #if (SSH_RSA_SIGN_SUPPORT == ENABLED)
82  //RSA certificate?
83  if(sshCompareString(&cert->keyFormatId, "ssh-rsa-cert") ||
84  sshCompareString(&cert->keyFormatId, "ssh-rsa-cert-v01@openssh.com"))
85  {
86  //Parse RSA public key
88  &cert->publicKey.rsaPublicKey);
89  }
90  else
91 #endif
92 #if (SSH_DSA_SIGN_SUPPORT == ENABLED)
93  //DSA certificate?
94  if(sshCompareString(&cert->keyFormatId, "ssh-dss-cert") ||
95  sshCompareString(&cert->keyFormatId, "ssh-dss-cert-v01@openssh.com"))
96  {
97  //Parse DSA public key
99  &cert->publicKey.dsaPublicKey);
100  }
101  else
102 #endif
103 #if (SSH_ECDSA_SIGN_SUPPORT == ENABLED)
104  //ECDSA certificate?
105  if(sshCompareString(&cert->keyFormatId, "ecdsa-sha2-nistp256-cert") ||
106  sshCompareString(&cert->keyFormatId, "ecdsa-sha2-nistp384-cert") ||
107  sshCompareString(&cert->keyFormatId, "ecdsa-sha2-nistp521-cert") ||
108  sshCompareString(&cert->keyFormatId, "ecdsa-sha2-nistp256-cert-v01@openssh.com") ||
109  sshCompareString(&cert->keyFormatId, "ecdsa-sha2-nistp384-cert-v01@openssh.com") ||
110  sshCompareString(&cert->keyFormatId, "ecdsa-sha2-nistp521-cert-v01@openssh.com"))
111  {
112  //Parse ECDSA public key
114  &cert->publicKey.ecdsaPublicKey);
115  }
116  else
117 #endif
118 #if (SSH_ED25519_SIGN_SUPPORT == ENABLED)
119  //Ed25519 certificate?
120  if(sshCompareString(&cert->keyFormatId, "ssh-ed25519-cert") ||
121  sshCompareString(&cert->keyFormatId, "ssh-ed25519-cert-v01@openssh.com"))
122  {
123  //Parse Ed25519 public key
125  &cert->publicKey.eddsaPublicKey);
126  }
127  else
128 #endif
129 #if (SSH_ED448_SIGN_SUPPORT == ENABLED)
130  //Ed448 certificate?
131  if(sshCompareString(&cert->keyFormatId, "ssh-ed448-cert"))
132  {
133  //Parse Ed448 public key
135  &cert->publicKey.eddsaPublicKey);
136  }
137  else
138 #endif
139  //Unknown certificate type?
140  {
141  //Report an error
142  error = ERROR_WRONG_IDENTIFIER;
143  }
144 
145  //Any error to report?
146  if(error)
147  return error;
148 
149  //Point to the next field
150  data += n;
151  length -= n;
152 
153  //Malformed certificate?
154  if(length < sizeof(uint64_t))
155  return ERROR_INVALID_SYNTAX;
156 
157  //Parse 'serial' field
158  cert->serial = LOAD64BE(data);
159 
160  //Point to the next field
161  data += sizeof(uint64_t);
162  length -= sizeof(uint64_t);
163 
164  //Malformed certificate?
165  if(length < sizeof(uint32_t))
166  return ERROR_INVALID_SYNTAX;
167 
168  //Parse 'type' field
169  cert->type = LOAD32BE(data);
170 
171  //Check certificate type
172  if(cert->type != SSH_CERT_TYPE_USER && cert->type != SSH_CERT_TYPE_HOST)
173  return ERROR_WRONG_TYPE;
174 
175  //Point to the next field
176  data += sizeof(uint32_t);
177  length -= sizeof(uint32_t);
178 
179  //Parse 'key id' field
180  error = sshParseString(data, length, &cert->keyId);
181  //Any error to report?
182  if(error)
183  return error;
184 
185  //Point to the next field
186  data += sizeof(uint32_t) + cert->keyId.length;
187  length -= sizeof(uint32_t) + cert->keyId.length;
188 
189  //Parse 'valid principals' field
191  //Any error to report?
192  if(error)
193  return error;
194 
195  //Point to the next field
196  data += sizeof(uint32_t) + cert->validPrincipals.length;
197  length -= sizeof(uint32_t) + cert->validPrincipals.length;
198 
199  //Malformed certificate?
200  if(length < sizeof(uint64_t))
201  return ERROR_INVALID_SYNTAX;
202 
203  //Parse 'valid after' field
204  cert->validAfter = LOAD64BE(data);
205 
206  //Point to the next field
207  data += sizeof(uint64_t);
208  length -= sizeof(uint64_t);
209 
210  //Malformed certificate?
211  if(length < sizeof(uint64_t))
212  return ERROR_INVALID_SYNTAX;
213 
214  //Parse 'valid before' field
215  cert->validBefore = LOAD64BE(data);
216 
217  //Point to the next field
218  data += sizeof(uint64_t);
219  length -= sizeof(uint64_t);
220 
221  //Parse 'critical options' field
223  //Any error to report?
224  if(error)
225  return error;
226 
227  //Point to the next field
228  data += sizeof(uint32_t) + cert->criticalOptions.length;
229  length -= sizeof(uint32_t) + cert->criticalOptions.length;
230 
231  //Parse 'extensions' field
232  error = sshParseExtensions(data, length, &cert->extensions);
233  //Any error to report?
234  if(error)
235  return error;
236 
237  //Point to the next field
238  data += sizeof(uint32_t) + cert->extensions.length;
239  length -= sizeof(uint32_t) + cert->extensions.length;
240 
241  //Parse 'reserved' field
242  error = sshParseBinaryString(data, length, &cert->reserved);
243  //Any error to report?
244  if(error)
245  return error;
246 
247  //Point to the next field
248  data += sizeof(uint32_t) + cert->reserved.length;
249  length -= sizeof(uint32_t) + cert->reserved.length;
250 
251  //Parse 'signature key' field
252  error = sshParseBinaryString(data, length, &cert->signatureKey);
253  //Any error to report?
254  if(error)
255  return error;
256 
257  //Point to the next field
258  data += sizeof(uint32_t) + cert->signatureKey.length;
259  length -= sizeof(uint32_t) + cert->signatureKey.length;
260 
261  //Parse 'signature' field
262  error = sshParseBinaryString(data, length, &cert->signature);
263  //Any error to report?
264  if(error)
265  return error;
266 
267  //Point to the next field
268  data += sizeof(uint32_t) + cert->signature.length;
269  length -= sizeof(uint32_t) + cert->signature.length;
270 
271  //Malformed certificate?
272  if(length != 0)
273  return ERROR_INVALID_SYNTAX;
274 
275  //Successful processing
276  return NO_ERROR;
277 }
278 
279 /**
280  * @brief Parse an RSA public key
281  * @param[in] data Pointer to the input data to parse
282  * @param[in] length Number of bytes available in the input data
283  * @param[in] consumed Number of bytes that have been consumed
284  * @param[out] publicKey Information resulting from the parsing process
285  * @return Error code
286  **/
287 
289  size_t *consumed, SshRsaCertPublicKey *publicKey)
290 {
291 #if (SSH_RSA_SIGN_SUPPORT == ENABLED)
292  error_t error;
293 
294  //Total number of bytes that have been consumed
295  *consumed = 0;
296 
297  //Parse RSA public exponent
298  error = sshParseBinaryString(data, length, &publicKey->e);
299  //Any error to report?
300  if(error)
301  return error;
302 
303  //Point to the next field
304  data += sizeof(uint32_t) + publicKey->e.length;
305  length -= sizeof(uint32_t) + publicKey->e.length;
306  *consumed += sizeof(uint32_t) + publicKey->e.length;
307 
308  //Parse RSA modulus
309  error = sshParseBinaryString(data, length, &publicKey->n);
310  //Any error to report?
311  if(error)
312  return error;
313 
314  //Point to the next field
315  data += sizeof(uint32_t) + publicKey->n.length;
316  length -= sizeof(uint32_t) + publicKey->n.length;
317  *consumed += sizeof(uint32_t) + publicKey->n.length;
318 
319  //Successful processing
320  return NO_ERROR;
321 #else
322  //Not implemented
323  return ERROR_NOT_IMPLEMENTED;
324 #endif
325 }
326 
327 
328 /**
329  * @brief Parse a DSA public key
330  * @param[in] data Pointer to the input data to parse
331  * @param[in] length Number of bytes available in the input data
332  * @param[in] consumed Number of bytes that have been consumed
333  * @param[out] publicKey Information resulting from the parsing process
334  * @return Error code
335  **/
336 
338  size_t *consumed, SshDsaCertPublicKey *publicKey)
339 {
340 #if (SSH_DSA_SIGN_SUPPORT == ENABLED)
341  error_t error;
342 
343  //Total number of bytes that have been consumed
344  *consumed = 0;
345 
346  //Parse DSA prime modulus
347  error = sshParseBinaryString(data, length, &publicKey->p);
348  //Any error to report?
349  if(error)
350  return error;
351 
352  //Point to the next field
353  data += sizeof(uint32_t) + publicKey->p.length;
354  length -= sizeof(uint32_t) + publicKey->p.length;
355  *consumed += sizeof(uint32_t) + publicKey->p.length;
356 
357  //Parse DSA group order
358  error = sshParseBinaryString(data, length, &publicKey->q);
359  //Any error to report?
360  if(error)
361  return error;
362 
363  //Point to the next field
364  data += sizeof(uint32_t) + publicKey->q.length;
365  length -= sizeof(uint32_t) + publicKey->q.length;
366  *consumed += sizeof(uint32_t) + publicKey->q.length;
367 
368  //Parse DSA group generator
369  error = sshParseBinaryString(data, length, &publicKey->g);
370  //Any error to report?
371  if(error)
372  return error;
373 
374  //Point to the next field
375  data += sizeof(uint32_t) + publicKey->g.length;
376  length -= sizeof(uint32_t) + publicKey->g.length;
377  *consumed += sizeof(uint32_t) + publicKey->g.length;
378 
379  //Parse DSA public key value
380  error = sshParseBinaryString(data, length, &publicKey->y);
381  //Any error to report?
382  if(error)
383  return error;
384 
385  //Point to the next field
386  data += sizeof(uint32_t) + publicKey->y.length;
387  length -= sizeof(uint32_t) + publicKey->y.length;
388  *consumed += sizeof(uint32_t) + publicKey->y.length;
389 
390  //Successful processing
391  return NO_ERROR;
392 #else
393  //Not implemented
394  return ERROR_NOT_IMPLEMENTED;
395 #endif
396 }
397 
398 
399 /**
400  * @brief Parse an ECDSA public key
401  * @param[in] data Pointer to the input data to parse
402  * @param[in] length Number of bytes available in the input data
403  * @param[in] consumed Number of bytes that have been consumed
404  * @param[out] publicKey Information resulting from the parsing process
405  * @return Error code
406  **/
407 
409  size_t *consumed, SshEcdsaCertPublicKey *publicKey)
410 {
411 #if (SSH_ECDSA_SIGN_SUPPORT == ENABLED)
412  error_t error;
413 
414  //Total number of bytes that have been consumed
415  *consumed = 0;
416 
417  //Parse curve name
418  error = sshParseString(data, length, &publicKey->curveName);
419  //Any error to report?
420  if(error)
421  return error;
422 
423  //Point to the next field
424  data += sizeof(uint32_t) + publicKey->curveName.length;
425  length -= sizeof(uint32_t) + publicKey->curveName.length;
426  *consumed += sizeof(uint32_t) + publicKey->curveName.length;
427 
428  //Parse EC public key
429  error = sshParseBinaryString(data, length, &publicKey->q);
430  //Any error to report?
431  if(error)
432  return error;
433 
434  //Point to the next field
435  data += sizeof(uint32_t) + publicKey->q.length;
436  length -= sizeof(uint32_t) + publicKey->q.length;
437  *consumed += sizeof(uint32_t) + publicKey->q.length;
438 
439  //Successful processing
440  return NO_ERROR;
441 #else
442  //Not implemented
443  return ERROR_NOT_IMPLEMENTED;
444 #endif
445 }
446 
447 
448 /**
449  * @brief Parse an EdDSA public key
450  * @param[in] data Pointer to the input data to parse
451  * @param[in] length Number of bytes available in the input data
452  * @param[in] consumed Number of bytes that have been consumed
453  * @param[out] publicKey Information resulting from the parsing process
454  * @return Error code
455  **/
456 
458  size_t *consumed, SshEddsaCertPublicKey *publicKey)
459 {
460 #if (SSH_ED25519_SIGN_SUPPORT == ENABLED || SSH_ED448_SIGN_SUPPORT == ENABLED)
461  error_t error;
462 
463  //Total number of bytes that have been consumed
464  *consumed = 0;
465 
466  //Parse EdDSA public key value
467  error = sshParseBinaryString(data, length, &publicKey->q);
468  //Any error to report?
469  if(error)
470  return error;
471 
472  //Point to the next field
473  data += sizeof(uint32_t) + publicKey->q.length;
474  length -= sizeof(uint32_t) + publicKey->q.length;
475  *consumed += sizeof(uint32_t) + publicKey->q.length;
476 
477  //Successful processing
478  return NO_ERROR;
479 #else
480  //Not implemented
481  return ERROR_NOT_IMPLEMENTED;
482 #endif
483 }
484 
485 
486 /**
487  * @brief Parse 'valid principals' field
488  * @param[in] data Pointer to the input data to parse
489  * @param[in] length Number of bytes available in the input data
490  * @param[out] validPrincipals Information resulting from the parsing process
491  * @return Error code
492  **/
493 
495  SshBinaryString *validPrincipals)
496 {
497  error_t error;
498  SshString name;
499 
500  //'valid principals' is a string containing zero or more principals as
501  //strings packed inside it
502  error = sshParseBinaryString(data, length, validPrincipals);
503 
504  //Check status code
505  if(!error)
506  {
507  //Check the length of the string
508  if(validPrincipals->length > 0)
509  {
510  //Point to the first item of the list
511  data = validPrincipals->value;
512  length = validPrincipals->length;
513 
514  //These principals list the names for which this certificate is
515  //valid; hostnames for SSH_CERT_TYPE_HOST certificates and usernames
516  //for SSH_CERT_TYPE_USER certificates
517  while(length > 0)
518  {
519  //Decode current name
520  error = sshParseString(data, length, &name);
521  //Any error to report?
522  if(error)
523  break;
524 
525  //Point to the next field
526  data += sizeof(uint32_t) + name.length;
527  length -= sizeof(uint32_t) + name.length;
528  }
529  }
530  else
531  {
532  //As a special case, a zero-length 'valid principals' field means the
533  //certificate is valid for any principal of the specified type
534  }
535  }
536 
537  //Return status code
538  return error;
539 }
540 
541 
542 /**
543  * @brief Parse 'critical options' field
544  * @param[in] data Pointer to the input data to parse
545  * @param[in] length Number of bytes available in the input data
546  * @param[out] criticalOptions Information resulting from the parsing process
547  * @return Error code
548  **/
549 
551  SshBinaryString *criticalOptions)
552 {
553  error_t error;
554  SshString optionName;
555  SshString optionData;
556 
557  //'critical options' is a set of zero or more key options. All such options
558  //are critical in the sense that an implementation must refuse to authorize
559  //a key that has an unrecognized option
560  error = sshParseBinaryString(data, length, criticalOptions);
561 
562  //Check status code
563  if(!error)
564  {
565  //Point to the first item of the list
566  data = criticalOptions->value;
567  length = criticalOptions->length;
568 
569  //Loop through critical options
570  while(length > 0)
571  {
572  //The name field identifies the option
573  error = sshParseString(data, length, &optionName);
574  //Any error to report?
575  if(error)
576  break;
577 
578  //Point to the next field
579  data += sizeof(uint32_t) + optionName.length;
580  length -= sizeof(uint32_t) + optionName.length;
581 
582  //The data field encodes option-specific information
583  error = sshParseString(data, length, &optionData);
584  //Any error to report?
585  if(error)
586  break;
587 
588  //Point to the next field
589  data += sizeof(uint32_t) + optionData.length;
590  length -= sizeof(uint32_t) + optionData.length;
591  }
592  }
593 
594  //Return status code
595  return error;
596 }
597 
598 
599 /**
600  * @brief Parse 'extensions' field
601  * @param[in] data Pointer to the input data to parse
602  * @param[in] length Number of bytes available in the input data
603  * @param[out] extensions Information resulting from the parsing process
604  * @return Error code
605  **/
606 
607 error_t sshParseExtensions(const uint8_t *data, size_t length,
609 {
610  error_t error;
611  SshString extensionName;
612  SshString extensionData;
613 
614  //'extensions' is a set of zero or more optional extensions. These extensions
615  //are not critical, and an implementation that encounters one that it does
616  //not recognize may safely ignore it
618 
619  //Check status code
620  if(!error)
621  {
622  //Point to the first item of the list
623  data = extensions->value;
624  length = extensions->length;
625 
626  //Loop through extensions
627  while(length > 0)
628  {
629  //The name field identifies the extension
630  error = sshParseString(data, length, &extensionName);
631  //Any error to report?
632  if(error)
633  break;
634 
635  //Point to the next field
636  data += sizeof(uint32_t) + extensionName.length;
637  length -= sizeof(uint32_t) + extensionName.length;
638 
639  //The data field encodes extension-specific information
640  error = sshParseString(data, length, &extensionData);
641  //Any error to report?
642  if(error)
643  break;
644 
645  //Point to the next field
646  data += sizeof(uint32_t) + extensionData.length;
647  length -= sizeof(uint32_t) + extensionData.length;
648  }
649  }
650 
651  //Return status code
652  return error;
653 }
654 
655 
656 /**
657  * @brief Extract the principal name at specified index
658  * @param[in] cert Pointer to the SSH certificate
659  * @param[in] index Zero-based index of the element to get
660  * @param[out] name Principal name
661  * @return TRUE if the index is valid, else FALSE
662  **/
663 
665  SshString *name)
666 {
667  error_t error;
668  uint_t i;
669  size_t length;
670  const uint8_t *p;
671 
672  //Point to the first item of the list
673  p = cert->validPrincipals.value;
674  length = cert->validPrincipals.length;
675 
676  //Loop through principals
677  for(i = 0; length > 0; i++)
678  {
679  //Decode current name
680  error = sshParseString(p, length, name);
681  //Any error to report?
682  if(error)
683  return FALSE;
684 
685  //Point to the next field
686  p += sizeof(uint32_t) + name->length;
687  length -= sizeof(uint32_t) + name->length;
688 
689  //Matching index?
690  if(i == index)
691  return TRUE;
692  }
693 
694  //The index is out of range
695  return FALSE;
696 }
697 
698 
699 /**
700  * @brief Extract the critical option at specified index
701  * @param[in] cert Pointer to the SSH certificate
702  * @param[in] index Zero-based index of the element to get
703  * @param[out] name Option name
704  * @param[out] data Option value
705  * @return TRUE if the index is valid, else FALSE
706  **/
707 
710 {
711  error_t error;
712  uint_t i;
713  size_t length;
714  const uint8_t *p;
715 
716  //Point to the first item of the list
717  p = cert->criticalOptions.value;
718  length = cert->criticalOptions.length;
719 
720  //Loop through critical options
721  for(i = 0; length > 0; i++)
722  {
723  //The name field identifies the option
724  error = sshParseString(p, length, name);
725  //Any error to report?
726  if(error)
727  break;
728 
729  //Point to the next field
730  p += sizeof(uint32_t) + name->length;
731  length -= sizeof(uint32_t) + name->length;
732 
733  //The data field encodes option-specific information
734  error = sshParseBinaryString(p, length, data);
735  //Any error to report?
736  if(error)
737  break;
738 
739  //Point to the next field
740  p += sizeof(uint32_t) + data->length;
741  length -= sizeof(uint32_t) + data->length;
742 
743  //Matching index?
744  if(i == index)
745  return TRUE;
746  }
747 
748  //The index is out of range
749  return FALSE;
750 }
751 
752 
753 /**
754  * @brief Extract the extension at specified index
755  * @param[in] cert Pointer to the SSH certificate
756  * @param[in] index Zero-based index of the element to get
757  * @param[out] name Extension name
758  * @param[out] data Extension value
759  * @return TRUE if the index is valid, else FALSE
760  **/
761 
764 {
765  error_t error;
766  uint_t i;
767  size_t length;
768  const uint8_t *p;
769 
770  //Point to the first item of the list
771  p = cert->extensions.value;
772  length = cert->extensions.length;
773 
774  //Loop through extensions
775  for(i = 0; length > 0; i++)
776  {
777  //The name field identifies the extension
778  error = sshParseString(p, length, name);
779  //Any error to report?
780  if(error)
781  break;
782 
783  //Point to the next field
784  p += sizeof(uint32_t) + name->length;
785  length -= sizeof(uint32_t) + name->length;
786 
787  //The data field encodes extension-specific information
788  error = sshParseBinaryString(p, length, data);
789  //Any error to report?
790  if(error)
791  break;
792 
793  //Point to the next field
794  p += sizeof(uint32_t) + data->length;
795  length -= sizeof(uint32_t) + data->length;
796 
797  //Matching index?
798  if(i == index)
799  return TRUE;
800  }
801 
802  //The index is out of range
803  return FALSE;
804 }
805 
806 #endif
error_t sshParseDsaCertPublicKey(const uint8_t *data, size_t length, size_t *consumed, SshDsaCertPublicKey *publicKey)
Parse a DSA public key.
EdDSA public key.
uint8_t extensions[]
Definition: ntp_common.h:207
int bool_t
Definition: compiler_port.h:61
#define LOAD32BE(p)
Definition: cpu_endian.h:210
@ ERROR_WRONG_TYPE
Definition: error.h:121
Binary string.
Definition: ssh_types.h:67
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
uint8_t p
Definition: ndp.h:300
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:224
error_t sshParseEddsaCertPublicKey(const uint8_t *data, size_t length, size_t *consumed, SshEddsaCertPublicKey *publicKey)
Parse an EdDSA public key.
bool_t sshGetExtension(const SshCertificate *cert, uint_t index, SshString *name, SshBinaryString *data)
Extract the extension at specified index.
SshRsaCertPublicKey rsaPublicKey
error_t sshParseString(const uint8_t *p, size_t length, SshString *string)
Parse a string.
Definition: ssh_misc.c:1167
SshBinaryString g
SshBinaryString q
SshBinaryString n
char_t name[]
size_t length
Definition: ssh_types.h:58
error_t sshParseRsaCertPublicKey(const uint8_t *data, size_t length, size_t *consumed, SshRsaCertPublicKey *publicKey)
Parse an RSA public key.
ECDSA public key.
bool_t sshCompareString(const SshString *string, const char_t *value)
Compare a binary string against the supplied value.
Definition: ssh_misc.c:1680
#define LOAD64BE(p)
Definition: cpu_endian.h:246
SshBinaryString p
size_t length
Definition: ssh_types.h:69
bool_t sshGetValidPrincipal(const SshCertificate *cert, uint_t index, SshString *name)
Extract the principal name at specified index.
#define FALSE
Definition: os_port.h:46
SshBinaryString validPrincipals
error_t
Error codes.
Definition: error.h:43
error_t sshParseValidPrincipals(const uint8_t *data, size_t length, SshBinaryString *validPrincipals)
Parse 'valid principals' field.
SshDsaCertPublicKey dsaPublicKey
@ SSH_CERT_TYPE_USER
SshBinaryString extensions
SSH certificate parsing.
DSA public key.
SshBinaryString reserved
uint64_t validAfter
SshEcdsaCertPublicKey ecdsaPublicKey
uint8_t length
Definition: tcp.h:375
SshBinaryString y
String.
Definition: ssh_types.h:56
error_t sshParseCriticalOptions(const uint8_t *data, size_t length, SshBinaryString *criticalOptions)
Parse 'critical options' field.
SshBinaryString q
SshBinaryString criticalOptions
const uint8_t * value
Definition: ssh_types.h:68
RSA public key.
SshBinaryString e
SshString keyFormatId
SshBinaryString signatureKey
SshCertPublicKey publicKey
uint8_t n
error_t sshParseExtensions(const uint8_t *data, size_t length, SshBinaryString *extensions)
Parse 'extensions' field.
uint64_t validBefore
error_t sshParseCertificate(const uint8_t *data, size_t length, SshCertificate *cert)
Parse SSH certificate.
SSH helper functions.
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
bool_t sshGetCriticalOption(const SshCertificate *cert, uint_t index, SshString *name, SshBinaryString *data)
Extract the critical option at specified index.
SshBinaryString nonce
error_t sshParseBinaryString(const uint8_t *p, size_t length, SshBinaryString *string)
Parse a binary string.
Definition: ssh_misc.c:1204
SshBinaryString signature
@ SSH_CERT_TYPE_HOST
unsigned int uint_t
Definition: compiler_port.h:57
#define osMemset(p, value, length)
Definition: os_port.h:138
error_t sshParseEcdsaCertPublicKey(const uint8_t *data, size_t length, size_t *consumed, SshEcdsaCertPublicKey *publicKey)
Parse an ECDSA public key.
Secure Shell (SSH)
SshEddsaCertPublicKey eddsaPublicKey
SSH certificate (OpenSSH format)
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
SshBinaryString q