summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--NEWS1
-rw-r--r--doc/api-keys.texi9
-rw-r--r--ssh/key-type.c43
-rw-r--r--ssh/key-type.h2
-rw-r--r--ssh/key.scm1
-rw-r--r--tests/key.scm12
7 files changed, 77 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 3895f1d..dac4b92 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2014-10-11 Artyom Poptsov <poptsov.artyom@gmail.com>
+ * ssh/key-type.c (_scm_from_ssh_key, guile_ssh_make_keypair): New
+ procedures.
+ * ssh/key-type.h: Update.
+ * ssh/key.scm (make-keypair): Export.
+ * doc/api-keys.texi (Keys): Add description of `make-keypair'.
+ * tests/key.scm ("make-keypair"): New TC.
+ * NEWS: Update.
+
* ssh/common.c (log_verbosity): Move to `ssh/log.c'.
* ssh/common.h, ssh/server-func.c, ssh/session-func.c: Update.
* ssh/log.scm (set-log-verbosity!, get-log-verbosity): Export.
@@ -9,6 +17,7 @@
* doc/api-logging.texi: Add descripton of `set-log-verbosity!' and
`get-log-verbosity'.
* NEWS: Update.
+
* tests/log.scm ("set-log-verbosity!", "get-log-verbosity"): New TCs.
* doc/api-keys.texi (Keys): Add note about support of ECDSA keys with
diff --git a/NEWS b/NEWS
index bb272fa..d9e310e 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ Copyright (C) Artyom V. Poptsov <poptsov.artyom@gmail.com>
** New `zlib-support?' procedure in (ssh version)
** New `set-log-verbosity!' procedure in (ssh log)
** New `get-log-verbosity' procedure in (ssh log)
+** New `make-keypair' procedure in (ssh key)
* Changes in version 0.7.0 (2014-08-31)
** Require GNU Guile 2.0
diff --git a/doc/api-keys.texi b/doc/api-keys.texi
index 24243fc..a787fd8 100644
--- a/doc/api-keys.texi
+++ b/doc/api-keys.texi
@@ -16,6 +16,15 @@ Guile-SSH keys.
@strong{Note} that Guile-SSH does not support ECDSA keys if libssh 0.6.3 is
compiled with GCrypt instead of OpenSSL.
+@deffn {Scheme Procedure} make-keypair type length
+Generate a keypair of specified @var{type} and @var{length} (in bits). This
+may take some time.
+
+Possible key types are: @code{dss}, @code{rsa}, @code{rsa1}, @code{ecdsa}.
+
+Return newly generated private key. Throw @code{guile-ssh-error} on error.
+@end deffn
+
@deffn {Scheme Procedure} key? x
Return @code{#t} if @var{x} is a Guile-SSH key, @code{#f} otherwise.
@end deffn
diff --git a/ssh/key-type.c b/ssh/key-type.c
index 20786d9..5b002b3 100644
--- a/ssh/key-type.c
+++ b/ssh/key-type.c
@@ -109,6 +109,37 @@ Possible types are: 'dss, 'rsa, 'rsa1, 'ecdsa, 'unknown\
return _ssh_key_type_to_scm (type);
}
+SCM_DEFINE (guile_ssh_make_keypair, "make-keypair", 2, 0, 0,
+ (SCM type, SCM length),
+ "\
+Generate a keypair of specified TYPE and LENGTH. This may take some time.\
+Return newly generated private key. Throw `guile-ssh-error' on error.\
+")
+#define FUNC_NAME s_guile_ssh_make_keypair
+{
+ ssh_key key = NULL;
+ struct symbol_mapping *c_type = _scm_to_ssh_key_type (type);
+ int c_length;
+ int res;
+
+ SCM_ASSERT (scm_is_unsigned_integer (length, 9, UINT32_MAX), length,
+ SCM_ARG2, FUNC_NAME);
+
+ if (! c_type)
+ guile_ssh_error1 (FUNC_NAME, "Wrong key type", type);
+
+ c_length = scm_to_int (length);
+ res = ssh_pki_generate (c_type->value, c_length, &key);
+ if (res == SSH_ERROR)
+ {
+ guile_ssh_error1 (FUNC_NAME, "Could not generate key",
+ scm_list_2 (type, length));
+ }
+
+ return _scm_from_ssh_key (key);
+}
+#undef FUNC_NAME
+
/* Predicates */
@@ -158,6 +189,18 @@ equalp_key (SCM x1, SCM x2)
/* Helper procedures */
+SCM
+_scm_from_ssh_key (ssh_key key)
+{
+ struct key_data *key_data;
+ SCM key_smob;
+ key_data = (struct key_data *) scm_gc_malloc (sizeof (struct key_data),
+ "ssh key");
+ key_data->ssh_key = key;
+ SCM_NEWSMOB (key_smob, key_tag, key_data);
+ return key_smob;
+}
+
/* Convert X to a SSH key */
struct key_data *
_scm_to_key_data (SCM x)
diff --git a/ssh/key-type.h b/ssh/key-type.h
index dc98568..80e8174 100644
--- a/ssh/key-type.h
+++ b/ssh/key-type.h
@@ -35,6 +35,7 @@ extern struct symbol_mapping key_types[];
/* Procedures */
+extern SCM guile_ssh_make_keypair (SCM arg1, SCM arg2);
extern SCM guile_ssh_is_key_p (SCM arg1);
extern SCM guile_ssh_is_public_key_p (SCM arg1);
extern SCM guile_ssh_is_private_key_p (SCM arg1);
@@ -45,6 +46,7 @@ extern void init_key_type (void);
/* Helper procedures */
+extern SCM _scm_from_ssh_key (ssh_key key);
extern struct key_data *_scm_to_key_data (SCM x);
extern inline int _private_key_p (struct key_data *key);
extern inline int _public_key_p (struct key_data *key);
diff --git a/ssh/key.scm b/ssh/key.scm
index a577cd4..0b02518 100644
--- a/ssh/key.scm
+++ b/ssh/key.scm
@@ -45,6 +45,7 @@
key?
public-key?
private-key?
+ make-keypair
get-key-type
public-key->string
string->public-key
diff --git a/tests/key.scm b/tests/key.scm
index 4ecb419..486efa0 100644
--- a/tests/key.scm
+++ b/tests/key.scm
@@ -122,6 +122,18 @@
(string=? (public-key->string (string->public-key %ecdsakey-pub-string 'ecdsa))
%ecdsakey-pub-string))))
+(test-assert "make-keypair"
+ (and (let ((key (make-keypair 'rsa 1024)))
+ (and (key? key)
+ (eq? (get-key-type key) 'rsa)))
+ (let ((key (make-keypair 'dss 1024)))
+ (and (key? key)
+ (eq? (get-key-type key) 'dss)))
+ (when-openssl
+ (let ((key (make-keypair 'ecdsa 256)))
+ (and (key? key)
+ (eq? (get-key-type key) 'ecdsa))))))
+
;;;
(test-end "key")