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.0
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
51  * @param[out] written Length of the resulting SSH public key file
52  * @param[in] format Desired output format (SSH2 or OpenSSH)
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(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
95  * @param[out] written Length of the resulting SSH public key file
96  * @param[in] format Desired output format (SSH2 or OpenSSH)
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(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
139  * @param[out] written Length of the resulting SSH public key file
140  * @param[in] format Desired output format (SSH2 or OpenSSH)
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 
151  //Check parameters
152  if(publicKey == NULL || written == NULL)
154 
155  //Format ECDSA host key structure
156  error = sshFormatEcdsaPublicKey(publicKey, (uint8_t *) output, &n);
157  //Any error to report?
158  if(error)
159  return error;
160 
161  //Convert the host key structure to the desired format
162  error = sshEncodePublicKeyFile(output, n, output, &n, format);
163  //Any error to report?
164  if(error)
165  return error;
166 
167  //Total number of bytes that have been written
168  *written = n;
169 
170  //Successful processing
171  return NO_ERROR;
172 #else
173  //Not implemented
174  return ERROR_NOT_IMPLEMENTED;
175 #endif
176 }
177 
178 
179 /**
180  * @brief Export a Ed25519 public key to SSH public key file format
181  * @param[in] publicKey Ed25519 public key
182  * @param[out] output Buffer where to store the SSH public key file
183  * @param[out] written Length of the resulting SSH public key file
184  * @param[in] format Desired output format (SSH2 or OpenSSH)
185  * @return Error code
186  **/
187 
189  char_t *output, size_t *written, SshPublicKeyFormat format)
190 
191 {
192 #if (SSH_ED25519_SIGN_SUPPORT == ENABLED)
193  error_t error;
194  size_t n;
195 
196  //Check parameters
197  if(publicKey == NULL || written == NULL)
199 
200  //Format Ed25519 host key structure
201  error = sshFormatEd25519PublicKey(publicKey, (uint8_t *) output, &n);
202  //Any error to report?
203  if(error)
204  return error;
205 
206  //Convert the host key structure to the desired format
207  error = sshEncodePublicKeyFile(output, n, output, &n, format);
208  //Any error to report?
209  if(error)
210  return error;
211 
212  //Total number of bytes that have been written
213  *written = n;
214 
215  //Successful processing
216  return NO_ERROR;
217 #else
218  //Not implemented
219  return ERROR_NOT_IMPLEMENTED;
220 #endif
221 }
222 
223 
224 /**
225  * @brief Export a Ed448 public key to SSH public key file format
226  * @param[in] publicKey Ed448 public key
227  * @param[out] output Buffer where to store the SSH public key file
228  * @param[out] written Length of the resulting SSH public key file
229  * @param[in] format Desired output format (SSH2 or OpenSSH)
230  * @return Error code
231  **/
232 
234  char_t *output, size_t *written, SshPublicKeyFormat format)
235 {
236 #if (SSH_ED448_SIGN_SUPPORT == ENABLED)
237  error_t error;
238  size_t n;
239 
240  //Check parameters
241  if(publicKey == NULL || written == NULL)
243 
244  //Format Ed448 host key structure
245  error = sshFormatEd448PublicKey(publicKey, (uint8_t *) output, &n);
246  //Any error to report?
247  if(error)
248  return error;
249 
250  //Convert the host key structure to the desired format
251  error = sshEncodePublicKeyFile(output, n, output, &n, format);
252  //Any error to report?
253  if(error)
254  return error;
255 
256  //Total number of bytes that have been written
257  *written = n;
258 
259  //Successful processing
260  return NO_ERROR;
261 #else
262  //Not implemented
263  return ERROR_NOT_IMPLEMENTED;
264 #endif
265 }
266 
267 
268 /**
269  * @brief Export an RSA private key to SSH private key file format
270  * @param[in] privateKey RSA private key
271  * @param[out] output Buffer where to store the SSH private key file
272  * @param[out] written Length of the resulting SSH private key file
273  * @param[in] format Desired output format (OpenSSH only is supported)
274  * @return Error code
275  **/
276 
278  char_t *output, size_t *written, SshPrivateKeyFormat format)
279 {
280  error_t error;
281 
282  //Check output format
283  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH)
284  {
285  //Export RSA private key file (OpenSSH format)
286  error = sshExportOpenSshRsaPrivateKey(privateKey, output, written);
287  }
288  else
289  {
290  //Invalid format
291  error = ERROR_INVALID_PARAMETER;
292  }
293 
294  //Return error code
295  return error;
296 }
297 
298 
299 /**
300  * @brief Export a DSA private key to SSH private key file format
301  * @param[in] privateKey DSA private key
302  * @param[out] output Buffer where to store the SSH private key file
303  * @param[out] written Length of the resulting SSH private key file
304  * @param[in] format Desired output format (OpenSSH only is supported)
305  * @return Error code
306  **/
307 
309  char_t *output, size_t *written, SshPrivateKeyFormat format)
310 {
311  error_t error;
312 
313  //Check output format
314  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH)
315  {
316  //Export DSA private key file (OpenSSH format)
317  error = sshExportOpenSshDsaPrivateKey(privateKey, output, written);
318  }
319  else
320  {
321  //Invalid format
322  error = ERROR_INVALID_PARAMETER;
323  }
324 
325  //Return error code
326  return error;
327 }
328 
329 
330 /**
331  * @brief Export an ECDSA private key to SSH private key file format
332  * @param[in] privateKey ECDSA private key
333  * @param[out] output Buffer where to store the SSH private key file
334  * @param[out] written Length of the resulting SSH private key file
335  * @param[in] format Desired output format (OpenSSH only is supported)
336  * @return Error code
337  **/
338 
340  char_t *output, size_t *written, SshPrivateKeyFormat format)
341 {
342  error_t error;
343 
344  //Check output format
345  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH)
346  {
347  //Export ECDSA private key file (OpenSSH format)
348  error = sshExportOpenSshEcdsaPrivateKey(privateKey, output, written);
349  }
350  else
351  {
352  //Invalid format
353  error = ERROR_INVALID_PARAMETER;
354  }
355 
356  //Return error code
357  return error;
358 }
359 
360 
361 /**
362  * @brief Export an Ed25519 private key to SSH private key file format
363  * @param[in] privateKey Ed25519 private key
364  * @param[out] output Buffer where to store the SSH private key file
365  * @param[out] written Length of the resulting SSH private key file
366  * @param[in] format Desired output format (OpenSSH only is supported)
367  * @return Error code
368  **/
369 
371  char_t *output, size_t *written, SshPrivateKeyFormat format)
372 {
373  error_t error;
374 
375  //Check output format
376  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH)
377  {
378  //Export Ed25519 private key file (OpenSSH format)
379  error = sshExportOpenSshEd25519PrivateKey(privateKey, output, written);
380  }
381  else
382  {
383  //Invalid format
384  error = ERROR_INVALID_PARAMETER;
385  }
386 
387  //Return error code
388  return error;
389 }
390 
391 
392 /**
393  * @brief Export an Ed448 private key to SSH private key file format
394  * @param[in] privateKey Ed448 private key
395  * @param[out] output Buffer where to store the SSH private key file
396  * @param[out] written Length of the resulting SSH private key file
397  * @param[in] format Desired output format (OpenSSH only is supported)
398  * @return Error code
399  **/
400 
402  char_t *output, size_t *written, SshPrivateKeyFormat format)
403 {
404  error_t error;
405 
406  //Check output format
407  if(format == SSH_PRIVATE_KEY_FORMAT_OPENSSH)
408  {
409  //Export Ed448 private key file (OpenSSH format)
410  error = sshExportOpenSshEd448PrivateKey(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 RSA private key to OpenSSH private key file format
425  * @param[in] privateKey RSA private key
426  * @param[out] output Buffer where to store the OpenSSH private key file
427  * @param[out] written Length of the resulting OpenSSH private key file
428  * @return Error code
429  **/
430 
432  char_t *output, size_t *written)
433 {
434 #if (SSH_RSA_SIGN_SUPPORT == ENABLED)
435  error_t error;
436  size_t n;
437  size_t length;
438  uint8_t *p;
439  RsaPublicKey publicKey;
440 
441  //Initialize variables
442  p = (uint8_t *) output;
443  length = 0;
444 
445  //Format private key header
447  //Any error to report?
448  if(error)
449  return error;
450 
451  //Point to the next field
452  p += n;
453  length += n;
454 
455  //The pair of numbers (n, e) form the RSA public key
456  publicKey.n = privateKey->n;
457  publicKey.e = privateKey->e;
458 
459  //Format 'publickey' field
460  error = sshFormatRsaPublicKey(&publicKey, p + sizeof(uint32_t), &n);
461  //Any error to report?
462  if(error)
463  return error;
464 
465  //The octet string value is preceded by a uint32 containing its length
466  STORE32BE(n, p);
467 
468  //Point to the next field
469  p += sizeof(uint32_t) + n;
470  length += sizeof(uint32_t) + n;
471 
472  //Format 'encrypted' field
473  error = sshFormatOpenSshRsaPrivateKey(privateKey, p + sizeof(uint32_t), &n);
474  //Any error to report?
475  if(error)
476  return error;
477 
478  //The octet string value is preceded by a uint32 containing its length
479  STORE32BE(n, p);
480 
481  //Total length of the private key structure
482  length += sizeof(uint32_t) + n;
483 
484  //Convert the private key structure to OpenSSH format
485  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
486  //Any error to report?
487  if(error)
488  return error;
489 
490  //Total number of bytes that have been written
491  *written = n;
492 
493  //Successful processing
494  return NO_ERROR;
495 #else
496  //Not implemented
497  return ERROR_NOT_IMPLEMENTED;
498 #endif
499 }
500 
501 
502 /**
503  * @brief Export a DSA private key to OpenSSH private key file format
504  * @param[in] privateKey DSA private key
505  * @param[out] output Buffer where to store the OpenSSH private key file
506  * @param[out] written Length of the resulting OpenSSH private key file
507  * @return Error code
508  **/
509 
511  char_t *output, size_t *written)
512 {
513 #if (SSH_DSA_SIGN_SUPPORT == ENABLED)
514  error_t error;
515  size_t n;
516  size_t length;
517  uint8_t *p;
518  DsaPublicKey publicKey;
519 
520  //Initialize variables
521  p = (uint8_t *) output;
522  length = 0;
523 
524  //Format private key header
526  //Any error to report?
527  if(error)
528  return error;
529 
530  //Point to the next field
531  p += n;
532  length += n;
533 
534  //These four parameters (p, q, g and y) form the DSA public key
535  publicKey.params = privateKey->params;
536  publicKey.y = privateKey->y;
537 
538  //Format 'publickey' field
539  error = sshFormatDsaPublicKey(&publicKey, p + sizeof(uint32_t), &n);
540  //Any error to report?
541  if(error)
542  return error;
543 
544  //The octet string value is preceded by a uint32 containing its length
545  STORE32BE(n, p);
546 
547  //Point to the next field
548  p += sizeof(uint32_t) + n;
549  length += sizeof(uint32_t) + n;
550 
551  //Format 'encrypted' field
552  error = sshFormatOpenSshDsaPrivateKey(privateKey, p + sizeof(uint32_t), &n);
553  //Any error to report?
554  if(error)
555  return error;
556 
557  //The octet string value is preceded by a uint32 containing its length
558  STORE32BE(n, p);
559 
560  //Total length of the private key structure
561  length += sizeof(uint32_t) + n;
562 
563  //Convert the private key structure to OpenSSH format
564  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
565  //Any error to report?
566  if(error)
567  return error;
568 
569  //Total number of bytes that have been written
570  *written = n;
571 
572  //Successful processing
573  return NO_ERROR;
574 #else
575  //Not implemented
576  return ERROR_NOT_IMPLEMENTED;
577 #endif
578 }
579 
580 
581 /**
582  * @brief Export an ECDSA private key to OpenSSH private key file format
583  * @param[in] privateKey ECDSA private key
584  * @param[out] output Buffer where to store the OpenSSH private key file
585  * @param[out] written Length of the resulting OpenSSH private key file
586  * @return Error code
587  **/
588 
590  char_t *output, size_t *written)
591 {
592 #if (SSH_ECDSA_SIGN_SUPPORT == ENABLED)
593  error_t error;
594  size_t n;
595  size_t length;
596  uint8_t *p;
597 
598  //Initialize variables
599  p = (uint8_t *) output;
600  length = 0;
601 
602  //Format private key header
604  //Any error to report?
605  if(error)
606  return error;
607 
608  //Point to the next field
609  p += n;
610  length += n;
611 
612  //Format 'publickey' field
613  error = sshFormatEcdsaPublicKey(&privateKey->q, p + sizeof(uint32_t), &n);
614  //Any error to report?
615  if(error)
616  return error;
617 
618  //The octet string value is preceded by a uint32 containing its length
619  STORE32BE(n, p);
620 
621  //Point to the next field
622  p += sizeof(uint32_t) + n;
623  length += sizeof(uint32_t) + n;
624 
625  //Format 'encrypted' field
626  error = sshFormatOpenSshEcdsaPrivateKey(privateKey,
627  p + sizeof(uint32_t), &n);
628  //Any error to report?
629  if(error)
630  return error;
631 
632  //The octet string value is preceded by a uint32 containing its length
633  STORE32BE(n, p);
634 
635  //Total length of the private key structure
636  length += sizeof(uint32_t) + n;
637 
638  //Convert the private key structure to OpenSSH format
639  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
640  //Any error to report?
641  if(error)
642  return error;
643 
644  //Total number of bytes that have been written
645  *written = n;
646 
647  //Successful processing
648  return NO_ERROR;
649 #else
650  //Not implemented
651  return ERROR_NOT_IMPLEMENTED;
652 #endif
653 }
654 
655 
656 /**
657  * @brief Export an Ed25519 private key to OpenSSH private key file format
658  * @param[in] privateKey Ed25519 private key
659  * @param[out] output Buffer where to store the OpenSSH private key file
660  * @param[out] written Length of the resulting OpenSSH private key file
661  * @return Error code
662  **/
663 
665  char_t *output, size_t *written)
666 {
667 #if (SSH_ED25519_SIGN_SUPPORT == ENABLED)
668  error_t error;
669  size_t n;
670  size_t length;
671  uint8_t *p;
672 
673  //Initialize variables
674  p = (uint8_t *) output;
675  length = 0;
676 
677  //Format private key header
679  //Any error to report?
680  if(error)
681  return error;
682 
683  //Point to the next field
684  p += n;
685  length += n;
686 
687  //Format 'publickey' field
688  error = sshFormatEd25519PublicKey(&privateKey->q, p + sizeof(uint32_t), &n);
689  //Any error to report?
690  if(error)
691  return error;
692 
693  //The octet string value is preceded by a uint32 containing its length
694  STORE32BE(n, p);
695 
696  //Point to the next field
697  p += sizeof(uint32_t) + n;
698  length += sizeof(uint32_t) + n;
699 
700  //Format 'encrypted' field
701  error = sshFormatOpenSshEd25519PrivateKey(privateKey,
702  p + sizeof(uint32_t), &n);
703  //Any error to report?
704  if(error)
705  return error;
706 
707  //The octet string value is preceded by a uint32 containing its length
708  STORE32BE(n, p);
709 
710  //Total length of the private key structure
711  length += sizeof(uint32_t) + n;
712 
713  //Convert the private key structure to OpenSSH format
714  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
715  //Any error to report?
716  if(error)
717  return error;
718 
719  //Total number of bytes that have been written
720  *written = n;
721 
722  //Successful processing
723  return NO_ERROR;
724 #else
725  //Not implemented
726  return ERROR_NOT_IMPLEMENTED;
727 #endif
728 }
729 
730 
731 /**
732  * @brief Export an Ed448 private key to OpenSSH private key file format
733  * @param[in] privateKey Ed448 private key
734  * @param[out] output Buffer where to store the OpenSSH private key file
735  * @param[out] written Length of the resulting OpenSSH private key file
736  * @return Error code
737  **/
738 
740  char_t *output, size_t *written)
741 {
742 #if (SSH_ED448_SIGN_SUPPORT == ENABLED)
743  error_t error;
744  size_t n;
745  size_t length;
746  uint8_t *p;
747 
748  //Initialize variables
749  p = (uint8_t *) output;
750  length = 0;
751 
752  //Format private key header
754  //Any error to report?
755  if(error)
756  return error;
757 
758  //Point to the next field
759  p += n;
760  length += n;
761 
762  //Format 'publickey' field
763  error = sshFormatEd448PublicKey(&privateKey->q, p + sizeof(uint32_t), &n);
764  //Any error to report?
765  if(error)
766  return error;
767 
768  //The octet string value is preceded by a uint32 containing its length
769  STORE32BE(n, p);
770 
771  //Point to the next field
772  p += sizeof(uint32_t) + n;
773  length += sizeof(uint32_t) + n;
774 
775  //Format 'encrypted' field
776  error = sshFormatOpenSshEd448PrivateKey(privateKey,
777  p + sizeof(uint32_t), &n);
778  //Any error to report?
779  if(error)
780  return error;
781 
782  //The octet string value is preceded by a uint32 containing its length
783  STORE32BE(n, p);
784 
785  //Total length of the private key structure
786  length += sizeof(uint32_t) + n;
787 
788  //Convert the private key structure to OpenSSH format
789  error = sshEncodeOpenSshPrivateKeyFile(output, length, output, &n);
790  //Any error to report?
791  if(error)
792  return error;
793 
794  //Total number of bytes that have been written
795  *written = n;
796 
797  //Successful processing
798  return NO_ERROR;
799 #else
800  //Not implemented
801  return ERROR_NOT_IMPLEMENTED;
802 #endif
803 }
804 
805 
806 /**
807  * @brief Encode SSH public key file (SSH2 or OpenSSH format)
808  * @param[in] input Host key structure to encode
809  * @param[in] inputLen Length of the host key structure to encode
810  * @param[out] output SSH public key file (optional parameter)
811  * @param[out] outputLen Length of the SSH public key file
812  * @param[in] format Desired output format (SSH2 or OpenSSH)
813  **/
814 
815 error_t sshEncodePublicKeyFile(const void *input, size_t inputLen,
816  char_t *output, size_t *outputLen, SshPublicKeyFormat format)
817 {
818  error_t error;
819 
820  //Check output format
821  if(format == SSH_PUBLIC_KEY_FORMAT_SSH2)
822  {
823  //Encode SSH public key file (SSH2 format)
824  error = sshEncodeSsh2PublicKeyFile(input, inputLen, output, outputLen);
825  }
826  else if(format == SSH_PUBLIC_KEY_FORMAT_OPENSSH)
827  {
828  //Encode SSH public key file (OpenSSH format)
829  error = sshEncodeOpenSshPublicKeyFile(input, inputLen, output, outputLen);
830  }
831  else
832  {
833  //Invalid format
834  error = ERROR_INVALID_PARAMETER;
835  }
836 
837  //Return error code
838  return error;
839 }
840 
841 
842 /**
843  * @brief Encode SSH public key file (SSH2 format)
844  * @param[in] input Host key structure to encode
845  * @param[in] inputLen Length of the host key structure to encode
846  * @param[out] output SSH public key file (optional parameter)
847  * @param[out] outputLen Length of the SSH public key file
848  **/
849 
850 error_t sshEncodeSsh2PublicKeyFile(const void *input, size_t inputLen,
851  char_t *output, size_t *outputLen)
852 {
853  size_t n;
854 
855  //Check parameters
856  if(input == NULL || outputLen == NULL)
858 
859  //Each line in the body must not be longer than 72 8-bit bytes excluding
860  //line termination characters (refer to RFC 4716, section 3.4)
861  base64EncodeMultiline(input, inputLen, output, &n, 70);
862 
863  //If the output parameter is NULL, then the function calculates the length
864  //of the resulting SSH public key file without copying any data
865  if(output != NULL)
866  {
867  //Make room for the begin marker
868  osMemmove(output + 33, output, n);
869 
870  //The first line of a conforming key file must be a begin marker (refer
871  //to RFC 4716, section 3.2)
872  osMemcpy(output, "---- BEGIN SSH2 PUBLIC KEY ----\r\n", 33);
873 
874  //The last line of a conforming key file must be an end marker (refer to
875  //RFC 4716, section 3.2)
876  osStrcpy(output + n + 33, "\r\n---- END SSH2 PUBLIC KEY ----\r\n");
877  }
878 
879  //Consider the length of the markers
880  n += osStrlen("---- BEGIN SSH2 PUBLIC KEY ----\r\n");
881  n += osStrlen("\r\n---- END SSH2 PUBLIC KEY ----\r\n");
882 
883  //Total number of bytes that have been written
884  *outputLen = n;
885 
886  //Successful processing
887  return NO_ERROR;
888 }
889 
890 
891 /**
892  * @brief Encode SSH public key file (OpenSSH format)
893  * @param[in] input Host key structure to encode
894  * @param[in] inputLen Length of the host key structure to encode
895  * @param[out] output SSH public key file (optional parameter)
896  * @param[out] outputLen Length of the SSH public key file
897  **/
898 
899 error_t sshEncodeOpenSshPublicKeyFile(const void *input, size_t inputLen,
900  char_t *output, size_t *outputLen)
901 {
902  error_t error;
903  size_t n;
904  SshString keyFormatId;
905  uint8_t identifier[40];
906 
907  //Check parameters
908  if(input == NULL || outputLen == NULL)
910 
911  //Parse host key structure
912  error = sshParseHostKey(input, inputLen, &keyFormatId);
913  //Any error to report?
914  if(error)
915  return error;
916 
917  //Sanity check
918  if(keyFormatId.length > sizeof(identifier))
919  return ERROR_WRONG_IDENTIFIER;
920 
921  //Save key format identifier
922  osMemcpy(identifier, keyFormatId.value, keyFormatId.length);
923 
924  //Encode the host key structure using Base64
925  base64Encode(input, inputLen, output, &n);
926 
927  //If the output parameter is NULL, then the function calculates the length
928  //of the resulting certificate file without copying any data
929  if(output != NULL)
930  {
931  //Make room for the identifier string
932  osMemmove(output + keyFormatId.length + 1, output, n + 1);
933  //Copy identifier string
934  osMemcpy(output, identifier, keyFormatId.length);
935  //The identifier must be followed by a whitespace character
936  output[keyFormatId.length] = ' ';
937  }
938 
939  //Consider the length of the identifier string
940  n += keyFormatId.length + 1;
941 
942  //Total number of bytes that have been written
943  *outputLen = n;
944 
945  //Successful processing
946  return NO_ERROR;
947 }
948 
949 
950 /**
951  * @brief Encode SSH private key file (OpenSSH format)
952  * @param[in] input Private key structure to encode
953  * @param[in] inputLen Length of the private key structure to encode
954  * @param[out] output SSH private key file (optional parameter)
955  * @param[out] outputLen Length of the SSH private key file
956  **/
957 
958 error_t sshEncodeOpenSshPrivateKeyFile(const void *input, size_t inputLen,
959  char_t *output, size_t *outputLen)
960 {
961  size_t n;
962 
963  //Check parameters
964  if(input == NULL || outputLen == NULL)
966 
967  //Encode the private key structure using Base64
968  base64EncodeMultiline(input, inputLen, output, &n, 70);
969 
970  //If the output parameter is NULL, then the function calculates the length
971  //of the resulting SSH private key file without copying any data
972  if(output != NULL)
973  {
974  //Make room for the begin marker
975  osMemmove(output + 37, output, n);
976 
977  //The first line of the private key file must be a begin marker
978  osMemcpy(output, "-----BEGIN OPENSSH PRIVATE KEY-----\r\n", 37);
979 
980  //The last line of the private key file must be an end marker
981  osStrcpy(output + n + 37, "\r\n-----END OPENSSH PRIVATE KEY-----\r\n");
982  }
983 
984  //Consider the length of the markers
985  n += osStrlen("-----BEGIN OPENSSH PRIVATE KEY-----\r\n");
986  n += osStrlen("\r\n-----END OPENSSH PRIVATE KEY-----\r\n");
987 
988  //Total number of bytes that have been written
989  *outputLen = n;
990 
991  //Successful processing
992  return NO_ERROR;
993 }
994 
995 #endif
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.
size_t length
Definition: ssh_types.h:58
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.
error_t sshEncodeOpenSshPublicKeyFile(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
Encode SSH public key file (OpenSSH 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
const char_t * value
Definition: ssh_types.h:57
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
@ 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.
String.
Definition: ssh_types.h:56
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.
error_t sshEncodePublicKeyFile(const void *input, size_t inputLen, char_t *output, size_t *outputLen, SshPublicKeyFormat format)
Encode SSH public key file (SSH2 or OpenSSH format)
SSH helper functions.
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
Mpi y
Public key value.
Definition: dsa.h:63
uint8_t identifier[]
EddsaPublicKey q
Public key.
Definition: eddsa.h:79
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:73
error_t sshParseHostKey(const uint8_t *data, size_t length, SshString *keyFormatId)
Parse host key structure.
Definition: ssh_key_parse.c:53
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
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.