ssh_key_export.c
Go to the documentation of this file.
1 /**
2  * @file ssh_key_export.c
3  * @brief SSH key file export functions
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_key_export.h"
37 #include "ssh/ssh_key_parse.h"
38 #include "ssh/ssh_key_format.h"
39 #include "ssh/ssh_misc.h"
40 #include "encoding/base64.h"
41 #include "debug.h"
42 
43 //Check SSH stack configuration
44 #if (SSH_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Export an RSA public key to SSH public key file format
49  * @param[in] publicKey RSA public key
50  * @param[out] output Buffer where to store the SSH public key file (optional parameter)
51  * @param[out] written Length of the resulting SSH public key file
52  * @param[in] format Desired output format (SSH2 or OpenSSH format)
53  * @return Error code
54  **/
55 
57  char_t *output, size_t *written, SshPublicKeyFormat format)
58 {
59 #if (SSH_RSA_SIGN_SUPPORT == ENABLED)
60  error_t error;
61  size_t n;
62 
63  //Check parameters
64  if(publicKey == NULL || written == NULL)
66 
67  //Format RSA host key structure
68  error = sshFormatRsaPublicKey(publicKey, (uint8_t *) output, &n);
69  //Any error to report?
70  if(error)
71  return error;
72 
73  //Convert the host key structure to the desired format
74  error = sshEncodePublicKeyFile("ssh-rsa", output, n, output, &n, format);
75  //Any error to report?
76  if(error)
77  return error;
78 
79  //Total number of bytes that have been written
80  *written = n;
81 
82  //Successful processing
83  return NO_ERROR;
84 #else
85  //Not implemented
86  return ERROR_NOT_IMPLEMENTED;
87 #endif
88 }
89 
90 
91 /**
92  * @brief Export a DSA public key to SSH public key file format
93  * @param[in] publicKey DSA public key
94  * @param[out] output Buffer where to store the SSH public key file (optional parameter)
95  * @param[out] written Length of the resulting SSH public key file
96  * @param[in] format Desired output format (SSH2 or OpenSSH format)
97  * @return Error code
98  **/
99 
101  char_t *output, size_t *written, SshPublicKeyFormat format)
102 {
103 #if (SSH_DSA_SIGN_SUPPORT == ENABLED)
104  error_t error;
105  size_t n;
106 
107  //Check parameters
108  if(publicKey == NULL || written == NULL)
110 
111  //Format DSA host key structure
112  error = sshFormatDsaPublicKey(publicKey, (uint8_t *) output, &n);
113  //Any error to report?
114  if(error)
115  return error;
116 
117  //Convert the host key structure to the desired format
118  error = sshEncodePublicKeyFile("ssh-dss", output, n, output, &n, format);
119  //Any error to report?
120  if(error)
121  return error;
122 
123  //Total number of bytes that have been written
124  *written = n;
125 
126  //Successful processing
127  return NO_ERROR;
128 #else
129  //Not implemented
130  return ERROR_NOT_IMPLEMENTED;
131 #endif
132 }
133 
134 
135 /**
136  * @brief Export an ECDSA public key to SSH public key file format
137  * @param[in] publicKey ECDSA public key
138  * @param[out] output Buffer where to store the SSH public key file (optional parameter)
139  * @param[out] written Length of the resulting SSH public key file
140  * @param[in] format Desired output format (SSH2 or OpenSSH format)
141  * @return Error code
142  **/
143 
145  char_t *output, size_t *written, SshPublicKeyFormat format)
146 {
147 #if (SSH_ECDSA_SIGN_SUPPORT == ENABLED)
148  error_t error;
149  size_t n;
150  const char_t *keyFormatId;
151 
152  //Check parameters
153  if(publicKey == NULL || written == NULL)
155 
156  //Invalid ECDSA public key?
157  if(publicKey->curve == NULL)
159 
160  //Check elliptic curve
161  if(osStrcmp(publicKey->curve->name, "secp256r1") == 0)
162  {
163  //Select NIST P-256 elliptic curve
164  keyFormatId = "ecdsa-sha2-nistp256";
165  }
166  else if(osStrcmp(publicKey->curve->name, "secp384r1") == 0)
167  {
168  //Select NIST P-384 elliptic curve
169  keyFormatId = "ecdsa-sha2-nistp384";
170  }
171  else if(osStrcmp(publicKey->curve->name, "secp521r1") == 0)
172  {
173  //Select NIST P-521 elliptic curve
174  keyFormatId = "ecdsa-sha2-nistp521";
175  }
176  else
177  {
178  //Unknown host key algorithm
180  }
181 
182  //Format ECDSA host key structure
183  error = sshFormatEcdsaPublicKey(publicKey, (uint8_t *) output, &n);
184  //Any error to report?
185  if(error)
186  return error;
187 
188  //Convert the host key structure to the desired format
189  error = sshEncodePublicKeyFile(keyFormatId, output, n, output, &n, format);
190  //Any error to report?
191  if(error)
192  return error;
193 
194  //Total number of bytes that have been written
195  *written = n;
196 
197  //Successful processing
198  return NO_ERROR;
199 #else
200  //Not implemented
201  return ERROR_NOT_IMPLEMENTED;
202 #endif
203 }
204 
205 
206 /**
207  * @brief Export a Ed25519 public key to SSH public key file format
208  * @param[in] publicKey Ed25519 public key
209  * @param[out] output Buffer where to store the SSH public key file (optional parameter)
210  * @param[out] written Length of the resulting SSH public key file
211  * @param[in] format Desired output format (SSH2 or OpenSSH format)
212  * @return Error code
213  **/
214 
216  char_t *output, size_t *written, SshPublicKeyFormat format)
217 
218 {
219 #if (SSH_ED25519_SIGN_SUPPORT == ENABLED)
220  error_t error;
221  size_t n;
222 
223  //Check parameters
224  if(publicKey == NULL || written == NULL)
226 
227  //Format Ed25519 host key structure
228  error = sshFormatEd25519PublicKey(publicKey, (uint8_t *) output, &n);
229  //Any error to report?
230  if(error)
231  return error;
232 
233  //Convert the host key structure to the desired format
234  error = sshEncodePublicKeyFile("ssh-ed25519", output, n, output, &n, format);
235  //Any error to report?
236  if(error)
237  return error;
238 
239  //Total number of bytes that have been written
240  *written = n;
241 
242  //Successful processing
243  return NO_ERROR;
244 #else
245  //Not implemented
246  return ERROR_NOT_IMPLEMENTED;
247 #endif
248 }
249 
250 
251 /**
252  * @brief Export a Ed448 public key to SSH public key file format
253  * @param[in] publicKey Ed448 public key
254  * @param[out] output Buffer where to store the SSH public key file (optional parameter)
255  * @param[out] written Length of the resulting SSH public key file
256  * @param[in] format Desired output format (SSH2 or OpenSSH format)
257  * @return Error code
258  **/
259 
261  char_t *output, size_t *written, SshPublicKeyFormat format)
262 {
263 #if (SSH_ED448_SIGN_SUPPORT == ENABLED)
264  error_t error;
265  size_t n;
266 
267  //Check parameters
268  if(publicKey == NULL || written == NULL)
270 
271  //Format Ed448 host key structure
272  error = sshFormatEd448PublicKey(publicKey, (uint8_t *) output, &n);
273  //Any error to report?
274  if(error)
275  return error;
276 
277  //Convert the host key structure to the desired format
278  error = sshEncodePublicKeyFile("ssh-ed448", output, n, output, &n, format);
279  //Any error to report?
280  if(error)
281  return error;
282 
283  //Total number of bytes that have been written
284  *written = n;
285 
286  //Successful processing
287  return NO_ERROR;
288 #else
289  //Not implemented
290  return ERROR_NOT_IMPLEMENTED;
291 #endif
292 }
293 
294 
295 /**
296  * @brief Export an RSA private key to SSH private key file format
297  * @param[in] privateKey RSA private key
298  * @param[out] output Buffer where to store the SSH private key file
299  * @param[out] written Length of the resulting SSH private key file
300  * @param[in] format Desired output format (OpenSSH format only)
301  * @return Error code
302  **/
303 
305  char_t *output, size_t *written, SshPrivateKeyFormat format)
306 {
307  error_t error;
308 
309  //Check output format
310  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH ||
312  {
313  //Export RSA private key file (OpenSSH format)
314  error = sshExportOpenSshRsaPrivateKey(privateKey, output, written);
315  }
316  else
317  {
318  //Invalid format
319  error = ERROR_INVALID_PARAMETER;
320  }
321 
322  //Return error code
323  return error;
324 }
325 
326 
327 /**
328  * @brief Export a DSA private key to SSH private key file format
329  * @param[in] privateKey DSA private key
330  * @param[out] output Buffer where to store the SSH private key file
331  * @param[out] written Length of the resulting SSH private key file
332  * @param[in] format Desired output format (OpenSSH format only)
333  * @return Error code
334  **/
335 
337  char_t *output, size_t *written, SshPrivateKeyFormat format)
338 {
339  error_t error;
340 
341  //Check output format
342  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH ||
344  {
345  //Export DSA private key file (OpenSSH format)
346  error = sshExportOpenSshDsaPrivateKey(privateKey, output, written);
347  }
348  else
349  {
350  //Invalid format
351  error = ERROR_INVALID_PARAMETER;
352  }
353 
354  //Return error code
355  return error;
356 }
357 
358 
359 /**
360  * @brief Export an ECDSA private key to SSH private key file format
361  * @param[in] privateKey ECDSA private key
362  * @param[out] output Buffer where to store the SSH private key file
363  * @param[out] written Length of the resulting SSH private key file
364  * @param[in] format Desired output format (OpenSSH format only)
365  * @return Error code
366  **/
367 
369  char_t *output, size_t *written, SshPrivateKeyFormat format)
370 {
371  error_t error;
372 
373  //Check output format
374  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH ||
376  {
377  //Export ECDSA private key file (OpenSSH format)
378  error = sshExportOpenSshEcdsaPrivateKey(privateKey, output, written);
379  }
380  else
381  {
382  //Invalid format
383  error = ERROR_INVALID_PARAMETER;
384  }
385 
386  //Return error code
387  return error;
388 }
389 
390 
391 /**
392  * @brief Export an Ed25519 private key to SSH private key file format
393  * @param[in] privateKey Ed25519 private key
394  * @param[out] output Buffer where to store the SSH private key file
395  * @param[out] written Length of the resulting SSH private key file
396  * @param[in] format Desired output format (OpenSSH format only)
397  * @return Error code
398  **/
399 
401  char_t *output, size_t *written, SshPrivateKeyFormat format)
402 {
403  error_t error;
404 
405  //Check output format
406  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH ||
408  {
409  //Export Ed25519 private key file (OpenSSH format)
410  error = sshExportOpenSshEd25519PrivateKey(privateKey, output, written);
411  }
412  else
413  {
414  //Invalid format
415  error = ERROR_INVALID_PARAMETER;
416  }
417 
418  //Return error code
419  return error;
420 }
421 
422 
423 /**
424  * @brief Export an Ed448 private key to SSH private key file format
425  * @param[in] privateKey Ed448 private key
426  * @param[out] output Buffer where to store the SSH private key file
427  * @param[out] written Length of the resulting SSH private key file
428  * @param[in] format Desired output format (OpenSSH format only)
429  * @return Error code
430  **/
431 
433  char_t *output, size_t *written, SshPrivateKeyFormat format)
434 {
435  error_t error;
436 
437  //Check output format
438  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH ||
440  {
441  //Export Ed448 private key file (OpenSSH format)
442  error = sshExportOpenSshEd448PrivateKey(privateKey, output, written);
443  }
444  else
445  {
446  //Invalid format
447  error = ERROR_INVALID_PARAMETER;
448  }
449 
450  //Return error code
451  return error;
452 }
453 
454 
455 /**
456  * @brief Export an RSA private key to OpenSSH private key file format
457  * @param[in] privateKey RSA private key
458  * @param[out] output Buffer where to store the OpenSSH private key file
459  * @param[out] written Length of the resulting OpenSSH private key file
460  * @return Error code
461  **/
462 
464  char_t *output, size_t *written)
465 {
466 #if (SSH_RSA_SIGN_SUPPORT == ENABLED)
467  error_t error;
468  size_t n;
469  size_t length;
470  uint8_t *p;
471  RsaPublicKey publicKey;
472 
473  //Initialize variables
474  p = (uint8_t *) output;
475  length = 0;
476 
477  //Format private key header
479  //Any error to report?
480  if(error)
481  return error;
482 
483  //Point to the next field
484  p = SSH_INC_POINTER(p, n);
485  length += n;
486 
487  //The pair of numbers (n, e) form the RSA public key
488  publicKey.n = privateKey->n;
489  publicKey.e = privateKey->e;
490 
491  //Format 'publickey' field
492  error = sshFormatRsaPublicKey(&publicKey,
493  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
494  //Any error to report?
495  if(error)
496  return error;
497 
498  //The octet string value is preceded by a uint32 containing its length
499  if(p != NULL)
500  {
501  STORE32BE(n, p);
502  }
503 
504  //Point to the next field
505  p = SSH_INC_POINTER(p, sizeof(uint32_t) + n);
506  length += sizeof(uint32_t) + n;
507 
508  //Format 'encrypted' field
509  error = sshFormatOpenSshRsaPrivateKey(privateKey,
510  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
511  //Any error to report?
512  if(error)
513  return error;
514 
515  //The octet string value is preceded by a uint32 containing its length
516  if(p != NULL)
517  {
518  STORE32BE(n, p);
519  }
520 
521  //Total length of the private key structure
522  length += sizeof(uint32_t) + n;
523 
524  //Convert the private key structure to OpenSSH format
525  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
526  //Any error to report?
527  if(error)
528  return error;
529 
530  //Total number of bytes that have been written
531  *written = n;
532 
533  //Successful processing
534  return NO_ERROR;
535 #else
536  //Not implemented
537  return ERROR_NOT_IMPLEMENTED;
538 #endif
539 }
540 
541 
542 /**
543  * @brief Export a DSA private key to OpenSSH private key file format
544  * @param[in] privateKey DSA private key
545  * @param[out] output Buffer where to store the OpenSSH private key file
546  * @param[out] written Length of the resulting OpenSSH private key file
547  * @return Error code
548  **/
549 
551  char_t *output, size_t *written)
552 {
553 #if (SSH_DSA_SIGN_SUPPORT == ENABLED)
554  error_t error;
555  size_t n;
556  size_t length;
557  uint8_t *p;
558  DsaPublicKey publicKey;
559 
560  //Initialize variables
561  p = (uint8_t *) output;
562  length = 0;
563 
564  //Format private key header
566  //Any error to report?
567  if(error)
568  return error;
569 
570  //Point to the next field
571  p = SSH_INC_POINTER(p, n);
572  length += n;
573 
574  //These four parameters (p, q, g and y) form the DSA public key
575  publicKey.params = privateKey->params;
576  publicKey.y = privateKey->y;
577 
578  //Format 'publickey' field
579  error = sshFormatDsaPublicKey(&publicKey,
580  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
581  //Any error to report?
582  if(error)
583  return error;
584 
585  //The octet string value is preceded by a uint32 containing its length
586  if(p != NULL)
587  {
588  STORE32BE(n, p);
589  }
590 
591  //Point to the next field
592  p = SSH_INC_POINTER(p, sizeof(uint32_t) + n);
593  length += sizeof(uint32_t) + n;
594 
595  //Format 'encrypted' field
596  error = sshFormatOpenSshDsaPrivateKey(privateKey,
597  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
598  //Any error to report?
599  if(error)
600  return error;
601 
602  //The octet string value is preceded by a uint32 containing its length
603  if(p != NULL)
604  {
605  STORE32BE(n, p);
606  }
607 
608  //Total length of the private key structure
609  length += sizeof(uint32_t) + n;
610 
611  //Convert the private key structure to OpenSSH format
612  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
613  //Any error to report?
614  if(error)
615  return error;
616 
617  //Total number of bytes that have been written
618  *written = n;
619 
620  //Successful processing
621  return NO_ERROR;
622 #else
623  //Not implemented
624  return ERROR_NOT_IMPLEMENTED;
625 #endif
626 }
627 
628 
629 /**
630  * @brief Export an ECDSA private key to OpenSSH private key file format
631  * @param[in] privateKey ECDSA private key
632  * @param[out] output Buffer where to store the OpenSSH private key file
633  * @param[out] written Length of the resulting OpenSSH private key file
634  * @return Error code
635  **/
636 
638  char_t *output, size_t *written)
639 {
640 #if (SSH_ECDSA_SIGN_SUPPORT == ENABLED)
641  error_t error;
642  size_t n;
643  size_t length;
644  uint8_t *p;
645 
646  //Initialize variables
647  p = (uint8_t *) output;
648  length = 0;
649 
650  //Format private key header
652  //Any error to report?
653  if(error)
654  return error;
655 
656  //Point to the next field
657  p = SSH_INC_POINTER(p, n);
658  length += n;
659 
660  //Format 'publickey' field
661  error = sshFormatEcdsaPublicKey(&privateKey->q,
662  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
663  //Any error to report?
664  if(error)
665  return error;
666 
667  //The octet string value is preceded by a uint32 containing its length
668  if(p != NULL)
669  {
670  STORE32BE(n, p);
671  }
672 
673  //Point to the next field
674  p = SSH_INC_POINTER(p, sizeof(uint32_t) + n);
675  length += sizeof(uint32_t) + n;
676 
677  //Format 'encrypted' field
678  error = sshFormatOpenSshEcdsaPrivateKey(privateKey,
679  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
680  //Any error to report?
681  if(error)
682  return error;
683 
684  //The octet string value is preceded by a uint32 containing its length
685  if(p != NULL)
686  {
687  STORE32BE(n, p);
688  }
689 
690  //Total length of the private key structure
691  length += sizeof(uint32_t) + n;
692 
693  //Convert the private key structure to OpenSSH format
694  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
695  //Any error to report?
696  if(error)
697  return error;
698 
699  //Total number of bytes that have been written
700  *written = n;
701 
702  //Successful processing
703  return NO_ERROR;
704 #else
705  //Not implemented
706  return ERROR_NOT_IMPLEMENTED;
707 #endif
708 }
709 
710 
711 /**
712  * @brief Export an Ed25519 private key to OpenSSH private key file format
713  * @param[in] privateKey Ed25519 private key
714  * @param[out] output Buffer where to store the OpenSSH private key file
715  * @param[out] written Length of the resulting OpenSSH private key file
716  * @return Error code
717  **/
718 
720  char_t *output, size_t *written)
721 {
722 #if (SSH_ED25519_SIGN_SUPPORT == ENABLED)
723  error_t error;
724  size_t n;
725  size_t length;
726  uint8_t *p;
727 
728  //Initialize variables
729  p = (uint8_t *) output;
730  length = 0;
731 
732  //Format private key header
734  //Any error to report?
735  if(error)
736  return error;
737 
738  //Point to the next field
739  p = SSH_INC_POINTER(p, n);
740  length += n;
741 
742  //Format 'publickey' field
743  error = sshFormatEd25519PublicKey(&privateKey->q,
744  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
745  //Any error to report?
746  if(error)
747  return error;
748 
749  //The octet string value is preceded by a uint32 containing its length
750  if(p != NULL)
751  {
752  STORE32BE(n, p);
753  }
754 
755  //Point to the next field
756  p = SSH_INC_POINTER(p, sizeof(uint32_t) + n);
757  length += sizeof(uint32_t) + n;
758 
759  //Format 'encrypted' field
760  error = sshFormatOpenSshEd25519PrivateKey(privateKey,
761  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
762  //Any error to report?
763  if(error)
764  return error;
765 
766  //The octet string value is preceded by a uint32 containing its length
767  if(p != NULL)
768  {
769  STORE32BE(n, p);
770  }
771 
772  //Total length of the private key structure
773  length += sizeof(uint32_t) + n;
774 
775  //Convert the private key structure to OpenSSH format
776  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
777  //Any error to report?
778  if(error)
779  return error;
780 
781  //Total number of bytes that have been written
782  *written = n;
783 
784  //Successful processing
785  return NO_ERROR;
786 #else
787  //Not implemented
788  return ERROR_NOT_IMPLEMENTED;
789 #endif
790 }
791 
792 
793 /**
794  * @brief Export an Ed448 private key to OpenSSH private key file format
795  * @param[in] privateKey Ed448 private key
796  * @param[out] output Buffer where to store the OpenSSH private key file
797  * @param[out] written Length of the resulting OpenSSH private key file
798  * @return Error code
799  **/
800 
802  char_t *output, size_t *written)
803 {
804 #if (SSH_ED448_SIGN_SUPPORT == ENABLED)
805  error_t error;
806  size_t n;
807  size_t length;
808  uint8_t *p;
809 
810  //Initialize variables
811  p = (uint8_t *) output;
812  length = 0;
813 
814  //Format private key header
816  //Any error to report?
817  if(error)
818  return error;
819 
820  //Point to the next field
821  p = SSH_INC_POINTER(p, n);
822  length += n;
823 
824  //Format 'publickey' field
825  error = sshFormatEd448PublicKey(&privateKey->q,
826  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
827  //Any error to report?
828  if(error)
829  return error;
830 
831  //The octet string value is preceded by a uint32 containing its length
832  if(p != NULL)
833  {
834  STORE32BE(n, p);
835  }
836 
837  //Point to the next field
838  p = SSH_INC_POINTER(p, sizeof(uint32_t) + n);
839  length += sizeof(uint32_t) + n;
840 
841  //Format 'encrypted' field
842  error = sshFormatOpenSshEd448PrivateKey(privateKey,
843  SSH_INC_POINTER(p, sizeof(uint32_t)), &n);
844  //Any error to report?
845  if(error)
846  return error;
847 
848  //The octet string value is preceded by a uint32 containing its length
849  if(p != NULL)
850  {
851  STORE32BE(n, p);
852  }
853 
854  //Total length of the private key structure
855  length += sizeof(uint32_t) + n;
856 
857  //Convert the private key structure to OpenSSH format
858  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
859  //Any error to report?
860  if(error)
861  return error;
862 
863  //Total number of bytes that have been written
864  *written = n;
865 
866  //Successful processing
867  return NO_ERROR;
868 #else
869  //Not implemented
870  return ERROR_NOT_IMPLEMENTED;
871 #endif
872 }
873 
874 
875 /**
876  * @brief Encode SSH public key file (SSH2 or OpenSSH format)
877  * @param[in] keyFormatId Key format identifier
878  * @param[in] input Host key structure to encode
879  * @param[in] inputLen Length of the host key structure to encode
880  * @param[out] output SSH public key file (optional parameter)
881  * @param[out] outputLen Length of the SSH public key file
882  * @param[in] format Desired output format (SSH2 or OpenSSH format)
883  **/
884 
885 error_t sshEncodePublicKeyFile(const char_t *keyFormatId, const void *input,
886  size_t inputLen, char_t *output, size_t *outputLen, SshPublicKeyFormat format)
887 {
888  error_t error;
889 
890  //Check output format
891  if(format == SSH_PUBLIC_KEY_FORMAT_SSH2)
892  {
893  //Encode SSH public key file (SSH2 format)
894  error = sshEncodeSsh2PublicKeyFile(input, inputLen, output, outputLen);
895  }
896  else if(format == SSH_PUBLIC_KEY_FORMAT_OPENSSH ||
898  {
899  //Encode SSH public key file (OpenSSH format)
900  error = sshEncodeOpenSshPublicKeyFile(keyFormatId, input, inputLen,
901  output, outputLen);
902  }
903  else
904  {
905  //Invalid format
906  error = ERROR_INVALID_PARAMETER;
907  }
908 
909  //Return error code
910  return error;
911 }
912 
913 
914 /**
915  * @brief Encode SSH public key file (SSH2 format)
916  * @param[in] input Host key structure to encode
917  * @param[in] inputLen Length of the host key structure to encode
918  * @param[out] output SSH public key file (optional parameter)
919  * @param[out] outputLen Length of the SSH public key file
920  **/
921 
922 error_t sshEncodeSsh2PublicKeyFile(const void *input, size_t inputLen,
923  char_t *output, size_t *outputLen)
924 {
925  size_t n;
926 
927  //Check parameters
928  if(outputLen == NULL)
930 
931  //Sanity check
932  if(input == NULL && output != NULL)
934 
935  //Each line in the body must not be longer than 72 8-bit bytes excluding
936  //line termination characters (refer to RFC 4716, section 3.4)
937  base64EncodeMultiline(input, inputLen, output, &n, 70);
938 
939  //If the output parameter is NULL, then the function calculates the length
940  //of the resulting SSH public key file without copying any data
941  if(output != NULL)
942  {
943  //Make room for the begin marker
944  osMemmove(output + 33, output, n);
945 
946  //The first line of a conforming key file must be a begin marker (refer
947  //to RFC 4716, section 3.2)
948  osMemcpy(output, "---- BEGIN SSH2 PUBLIC KEY ----\r\n", 33);
949 
950  //The last line of a conforming key file must be an end marker (refer to
951  //RFC 4716, section 3.2)
952  osStrcpy(output + n + 33, "\r\n---- END SSH2 PUBLIC KEY ----\r\n");
953  }
954 
955  //Consider the length of the markers
956  n += osStrlen("---- BEGIN SSH2 PUBLIC KEY ----\r\n");
957  n += osStrlen("\r\n---- END SSH2 PUBLIC KEY ----\r\n");
958 
959  //Total number of bytes that have been written
960  *outputLen = n;
961 
962  //Successful processing
963  return NO_ERROR;
964 }
965 
966 
967 /**
968  * @brief Encode SSH public key file (OpenSSH format)
969  * @param[in] keyFormatId Key format identifier
970  * @param[in] input Host key structure to encode
971  * @param[in] inputLen Length of the host key structure to encode
972  * @param[out] output SSH public key file (optional parameter)
973  * @param[out] outputLen Length of the SSH public key file
974  **/
975 
977  const void *input, size_t inputLen, char_t *output, size_t *outputLen)
978 {
979  size_t n;
980  size_t keyFormatIdLen;
981 
982  //Check parameters
983  if(keyFormatId == NULL || outputLen == NULL)
985 
986  //Sanity check
987  if(input == NULL && output != NULL)
989 
990  //Get the length of the key format identifier
991  keyFormatIdLen = osStrlen(keyFormatId);
992 
993  //Encode the host key structure using Base64
994  base64Encode(input, inputLen, output, &n);
995 
996  //If the output parameter is NULL, then the function calculates the length
997  //of the resulting certificate file without copying any data
998  if(output != NULL)
999  {
1000  //Make room for the identifier string
1001  osMemmove(output + keyFormatIdLen + 1, output, n + 1);
1002  //Copy identifier string
1003  osMemcpy(output, keyFormatId, keyFormatIdLen);
1004  //The identifier must be followed by a whitespace character
1005  output[keyFormatIdLen] = ' ';
1006  }
1007 
1008  //Consider the length of the identifier string
1009  n += keyFormatIdLen + 1;
1010 
1011  //Total number of bytes that have been written
1012  *outputLen = n;
1013 
1014  //Successful processing
1015  return NO_ERROR;
1016 }
1017 
1018 
1019 /**
1020  * @brief Encode SSH private key file (OpenSSH format)
1021  * @param[in] input Private key structure to encode
1022  * @param[in] inputLen Length of the private key structure to encode
1023  * @param[out] output SSH private key file (optional parameter)
1024  * @param[out] outputLen Length of the SSH private key file
1025  **/
1026 
1027 error_t sshEncodeOpenSshPrivateKeyFile(const void *input, size_t inputLen,
1028  char_t *output, size_t *outputLen)
1029 {
1030  size_t n;
1031 
1032  //Check parameters
1033  if(outputLen == NULL)
1034  return ERROR_INVALID_PARAMETER;
1035 
1036  //Sanity check
1037  if(input == NULL && output != NULL)
1038  return ERROR_INVALID_PARAMETER;
1039 
1040  //Encode the private key structure using Base64
1041  base64EncodeMultiline(input, inputLen, output, &n, 70);
1042 
1043  //If the output parameter is NULL, then the function calculates the length
1044  //of the resulting SSH private key file without copying any data
1045  if(output != NULL)
1046  {
1047  //Make room for the begin marker
1048  osMemmove(output + 37, output, n);
1049 
1050  //The first line of the private key file must be a begin marker
1051  osMemcpy(output, "-----BEGIN OPENSSH PRIVATE KEY-----\r\n", 37);
1052 
1053  //The last line of the private key file must be an end marker
1054  osStrcpy(output + n + 37, "\r\n-----END OPENSSH PRIVATE KEY-----\r\n");
1055  }
1056 
1057  //Consider the length of the markers
1058  n += osStrlen("-----BEGIN OPENSSH PRIVATE KEY-----\r\n");
1059  n += osStrlen("\r\n-----END OPENSSH PRIVATE KEY-----\r\n");
1060 
1061  //Total number of bytes that have been written
1062  *outputLen = n;
1063 
1064  //Successful processing
1065  return NO_ERROR;
1066 }
1067 
1068 #endif
@ SSH_PRIVATE_KEY_FORMAT_DEFAULT
Default private key format.
@ ERROR_UNSUPPORTED_ELLIPTIC_CURVE
Definition: error.h:133
error_t sshFormatOpenSshPrivateKeyHeader(uint8_t *p, size_t *written)
Format private key header (OpenSSH format)
error_t sshFormatOpenSshEd25519PrivateKey(const EddsaPrivateKey *privateKey, uint8_t *p, size_t *written)
Format Ed25519 private key blob (OpenSSH format)
error_t sshFormatOpenSshEcdsaPrivateKey(const EcPrivateKey *privateKey, uint8_t *p, size_t *written)
Format ECDSA private key blob (OpenSSH format)
error_t sshExportEd25519PrivateKey(const EddsaPrivateKey *privateKey, char_t *output, size_t *written, SshPrivateKeyFormat format)
Export an Ed25519 private key to SSH private key file format.
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
error_t sshFormatOpenSshRsaPrivateKey(const RsaPrivateKey *privateKey, uint8_t *p, size_t *written)
Format RSA private key blob (OpenSSH format)
uint8_t p
Definition: ndp.h:300
void base64Encode(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
Base64 encoding algorithm.
Definition: base64.c:142
Mpi n
Modulus.
Definition: rsa.h:69
error_t sshExportRsaPublicKey(const RsaPublicKey *publicKey, char_t *output, size_t *written, SshPublicKeyFormat format)
Export an RSA public key to SSH public key file format.
error_t sshFormatOpenSshEd448PrivateKey(const EddsaPrivateKey *privateKey, uint8_t *p, size_t *written)
Format Ed448 private key blob (OpenSSH format)
error_t sshExportEcdsaPublicKey(const EcPublicKey *publicKey, char_t *output, size_t *written, SshPublicKeyFormat format)
Export an ECDSA public key to SSH public key file format.
#define osStrcmp(s1, s2)
Definition: os_port.h:174
SSH key parsing.
Mpi e
Public exponent.
Definition: rsa.h:59
#define osStrlen(s)
Definition: os_port.h:168
error_t sshExportOpenSshRsaPrivateKey(const RsaPrivateKey *privateKey, char_t *output, size_t *written)
Export an RSA private key to OpenSSH private key file format.
error_t sshFormatEd448PublicKey(const EddsaPublicKey *publicKey, uint8_t *p, size_t *written)
Format an Ed448 public host key.
void base64EncodeMultiline(const void *input, size_t inputLen, char_t *output, size_t *outputLen, size_t lineWidth)
Base64 multiline encoding.
Definition: base64.c:79
Mpi n
Modulus.
Definition: rsa.h:58
error_t sshFormatRsaPublicKey(const RsaPublicKey *publicKey, uint8_t *p, size_t *written)
Format an RSA public host key.
error_t sshExportOpenSshEd448PrivateKey(const EddsaPrivateKey *privateKey, char_t *output, size_t *written)
Export an Ed448 private key to OpenSSH private key file format.
error_t sshExportOpenSshEcdsaPrivateKey(const EcPrivateKey *privateKey, char_t *output, size_t *written)
Export an ECDSA private key to OpenSSH private key file format.
DSA public key.
Definition: dsa.h:61
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
SshPublicKeyFormat
SSH public key formats.
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t
Error codes.
Definition: error.h:43
EdDSA public key.
Definition: eddsa.h:64
error_t sshExportDsaPrivateKey(const DsaPrivateKey *privateKey, char_t *output, size_t *written, SshPrivateKeyFormat format)
Export a DSA private key to SSH private key file format.
@ SSH_PUBLIC_KEY_FORMAT_OPENSSH
OpenSSH public key format.
error_t sshFormatOpenSshDsaPrivateKey(const DsaPrivateKey *privateKey, uint8_t *p, size_t *written)
Format DSA private key blob (OpenSSH format)
RSA public key.
Definition: rsa.h:57
#define SSH_INC_POINTER(p, n)
@ SSH_PRIVATE_KEY_FORMAT_OPENSSH
OpenSSH private key format.
error_t sshFormatEd25519PublicKey(const EddsaPublicKey *publicKey, uint8_t *p, size_t *written)
Format an Ed25519 public host key.
Mpi y
Public key value.
Definition: dsa.h:75
EcPublicKey q
Public key.
Definition: ec.h:436
error_t sshEncodeOpenSshPrivateKeyFile(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
Encode SSH private key file (OpenSSH format)
Base64 encoding scheme.
EC private key.
Definition: ec.h:432
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:62
DSA private key.
Definition: dsa.h:72
SSH key formatting.
uint8_t length
Definition: tcp.h:375
Mpi e
Public exponent.
Definition: rsa.h:70
error_t sshExportOpenSshEd25519PrivateKey(const EddsaPrivateKey *privateKey, char_t *output, size_t *written)
Export an Ed25519 private key to OpenSSH private key file format.
error_t sshEncodePublicKeyFile(const char_t *keyFormatId, const void *input, size_t inputLen, char_t *output, size_t *outputLen, SshPublicKeyFormat format)
Encode SSH public key file (SSH2 or OpenSSH format)
error_t sshExportEcdsaPrivateKey(const EcPrivateKey *privateKey, char_t *output, size_t *written, SshPrivateKeyFormat format)
Export an ECDSA private key to SSH private key file format.
error_t sshFormatDsaPublicKey(const DsaPublicKey *publicKey, uint8_t *p, size_t *written)
Format a DSA public host key.
EdDSA private key.
Definition: eddsa.h:75
error_t sshExportRsaPrivateKey(const RsaPrivateKey *privateKey, char_t *output, size_t *written, SshPrivateKeyFormat format)
Export an RSA private key to SSH private key file format.
EC public key.
Definition: ec.h:421
char char_t
Definition: compiler_port.h:55
@ SSH_PUBLIC_KEY_FORMAT_SSH2
SSH2 public key format.
uint8_t n
RSA private key.
Definition: rsa.h:68
SshPrivateKeyFormat
SSH private key formats.
error_t sshExportDsaPublicKey(const DsaPublicKey *publicKey, char_t *output, size_t *written, SshPublicKeyFormat format)
Export a DSA public key to SSH public key file format.
SSH helper functions.
Mpi y
Public key value.
Definition: dsa.h:63
error_t sshEncodeOpenSshPublicKeyFile(const char_t *keyFormatId, const void *input, size_t inputLen, char_t *output, size_t *outputLen)
Encode SSH public key file (OpenSSH format)
EddsaPublicKey q
Public key.
Definition: eddsa.h:79
@ SSH_PUBLIC_KEY_FORMAT_DEFAULT
Default public key format.
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:73
@ ERROR_UNSUPPORTED_SIGNATURE_ALGO
Definition: error.h:132
error_t sshEncodeSsh2PublicKeyFile(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
Encode SSH public key file (SSH2 format)
error_t sshExportEd448PublicKey(const EddsaPublicKey *publicKey, char_t *output, size_t *written, SshPublicKeyFormat format)
Export a Ed448 public key to SSH public key file format.
Secure Shell (SSH)
error_t sshExportEd25519PublicKey(const EddsaPublicKey *publicKey, char_t *output, size_t *written, SshPublicKeyFormat format)
Export a Ed25519 public key to SSH public key file format.
#define osStrcpy(s1, s2)
Definition: os_port.h:210
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:422
error_t sshExportOpenSshDsaPrivateKey(const DsaPrivateKey *privateKey, char_t *output, size_t *written)
Export a DSA private key to OpenSSH private key file format.
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
error_t sshFormatEcdsaPublicKey(const EcPublicKey *publicKey, uint8_t *p, size_t *written)
Format an ECDSA public host key.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
#define osMemmove(dest, src, length)
Definition: os_port.h:150
SSH key file export functions.
error_t sshExportEd448PrivateKey(const EddsaPrivateKey *privateKey, char_t *output, size_t *written, SshPrivateKeyFormat format)
Export an Ed448 private key to SSH private key file format.