@@ -486,6 +486,111 @@ Return a fingerprint string on success, #f on error.\
486486}
487487#undef FUNC_NAME
488488
489+ static gssh_symbol_t sshsig_hash_types [] = {
490+ { "sha256" , SSHSIG_DIGEST_SHA2_256 },
491+ { "sha512" , SSHSIG_DIGEST_SHA2_512 },
492+ { NULL , -1 }
493+ };
494+
495+ SCM_DEFINE (guile_ssh_sign , "%sshsig-sign" , 4 , 0 , 0 ,
496+ (SCM data_bv , SCM private_key , SCM sig_namespace , SCM hash_alg ),
497+ "\
498+ Sign binary DATA_BV (bytevector) using a PRIVATE_KEY with specified SIG_NAMESPACE and HASH_ALG.\n\
499+ HASH_ALG should be 'sha256 or 'sha512.\n\
500+ Return the armored signature string on success, #f on error.\
501+ " )
502+ #define FUNC_NAME s_guile_ssh_sign
503+ {
504+ gssh_key_t * kd = gssh_key_from_scm (private_key );
505+ char * c_sig_namespace = NULL ;
506+ char * armored_sig = NULL ;
507+ const void * data ;
508+ size_t data_len ;
509+ const gssh_symbol_t * hash_type = NULL ;
510+ int res ;
511+ SCM ret ;
512+
513+ SCM_ASSERT (scm_is_bytevector (data_bv ), data_bv , SCM_ARG1 , FUNC_NAME );
514+ SCM_ASSERT (_private_key_p (kd ), private_key , SCM_ARG2 , FUNC_NAME );
515+ SCM_ASSERT (scm_is_string (sig_namespace ), sig_namespace , SCM_ARG3 , FUNC_NAME );
516+ SCM_ASSERT (scm_is_symbol (hash_alg ), hash_alg , SCM_ARG4 , FUNC_NAME );
517+
518+ scm_dynwind_begin (0 );
519+
520+ data_len = scm_c_bytevector_length (data_bv );
521+ data = SCM_BYTEVECTOR_CONTENTS (data_bv );
522+
523+ c_sig_namespace = scm_to_locale_string (sig_namespace );
524+ scm_dynwind_free (c_sig_namespace );
525+
526+ hash_type = gssh_symbol_from_scm (sshsig_hash_types , hash_alg );
527+ if (! hash_type )
528+ guile_ssh_error1 (FUNC_NAME , "Wrong hash type" , hash_alg );
529+
530+ res = sshsig_sign (data , data_len , kd -> ssh_key , c_sig_namespace ,
531+ hash_type -> value , & armored_sig );
532+
533+ if (res == SSH_OK )
534+ {
535+ ret = scm_take_locale_string (armored_sig );
536+ }
537+ else
538+ {
539+ ret = SCM_BOOL_F ;
540+ }
541+
542+ scm_dynwind_end ();
543+ return ret ;
544+ }
545+ #undef FUNC_NAME
546+
547+ SCM_DEFINE (guile_ssh_verify , "%sshsig-verify" , 3 , 0 , 0 ,
548+ (SCM data_bv , SCM signature , SCM sig_namespace ),
549+ "\
550+ Verify a SIGNATURE for binary DATA_BV (bytevector) with SIG_NAMESPACE.\n\
551+ Return the signing key on success, #f on error.\
552+ " )
553+ #define FUNC_NAME s_guile_ssh_verify
554+ {
555+ char * c_signature = NULL ;
556+ char * c_sig_namespace = NULL ;
557+ const void * data ;
558+ size_t data_len ;
559+ ssh_key sign_key = NULL ;
560+ int res ;
561+ SCM ret ;
562+
563+ SCM_ASSERT (scm_is_bytevector (data_bv ), data_bv , SCM_ARG1 , FUNC_NAME );
564+ SCM_ASSERT (scm_is_string (signature ), signature , SCM_ARG2 , FUNC_NAME );
565+ SCM_ASSERT (scm_is_string (sig_namespace ), sig_namespace , SCM_ARG3 , FUNC_NAME );
566+
567+ scm_dynwind_begin (0 );
568+
569+ data_len = scm_c_bytevector_length (data_bv );
570+ data = SCM_BYTEVECTOR_CONTENTS (data_bv );
571+
572+ c_signature = scm_to_locale_string (signature );
573+ scm_dynwind_free (c_signature );
574+
575+ c_sig_namespace = scm_to_locale_string (sig_namespace );
576+ scm_dynwind_free (c_sig_namespace );
577+
578+ res = sshsig_verify (data , data_len , c_signature , c_sig_namespace , & sign_key );
579+
580+ if (res == SSH_OK )
581+ {
582+ ret = gssh_key_to_scm (sign_key , SCM_BOOL_F );
583+ }
584+ else
585+ {
586+ ret = SCM_BOOL_F ;
587+ }
588+
589+ scm_dynwind_end ();
590+ return ret ;
591+ }
592+ #undef FUNC_NAME
593+
489594
490595/* Initialize Scheme procedures. */
491596void
0 commit comments