Bugzilla – Attachment 1497 Details for
Bug 1371
Add PKCS#11 (Smartcards) support into OpenSSH
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
2001_all_pkcs11-core.patch
2001_all_pkcs11-core.patch (text/plain), 23.01 KB, created by
Alon Bar-Lev
on 2008-04-27 07:02:42 AEST
(
hide
)
Description:
2001_all_pkcs11-core.patch
Filename:
MIME Type:
Creator:
Alon Bar-Lev
Created:
2008-04-27 07:02:42 AEST
Size:
23.01 KB
patch
obsolete
>[PATCH] PKCS#11 core module > >Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com> > >--- > >diff -urNp ssh/pkcs11.c ssh.new/pkcs11.c >--- ssh/pkcs11.c 1970-01-01 02:00:00.000000000 +0200 >+++ ssh.new/pkcs11.c 2008-04-26 23:53:26.000000000 +0300 >@@ -0,0 +1,844 @@ >+/* >+ * Copyright(c) 2005-2006 Alon Bar-Lev. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR >+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES >+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. >+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, >+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT >+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ *(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifdef ENABLE_PKCS11 >+ >+#include <string.h> >+#include <unistd.h> >+#include <sys/wait.h> >+#include <errno.h> >+#include <pkcs11-helper-1.0/pkcs11h-certificate.h> >+#include <pkcs11-helper-1.0/pkcs11h-openssl.h> >+#include "openssl/pem.h" >+#include "misc.h" >+#include "buffer.h" >+#include "xmalloc.h" >+#include "log.h" >+#include "pkcs11.h" >+ >+static char * >+ssh_from_x509(X509 *); >+ >+static time_t >+mytime(void) >+{ >+ return time(NULL); >+} >+ >+static void >+mysleep(const unsigned long usec) >+{ >+ usleep((unsigned)usec); >+} >+ >+static int >+mygettimeofday(struct timeval *tv) >+{ >+ return gettimeofday(tv, NULL); >+} >+ >+static pkcs11h_engine_system_t s_pkcs11h_sys_engine = { >+ xmalloc, >+ xfree, >+ mytime, >+ mysleep, >+ mygettimeofday >+}; >+ >+static LogLevel >+pkcs11_msg_pkcs112openssh(const unsigned flags) >+{ >+ LogLevel openssh_flags; >+ >+ switch (flags) { >+ case PKCS11H_LOG_DEBUG2: >+ openssh_flags = SYSLOG_LEVEL_DEBUG3; >+ break; >+ case PKCS11H_LOG_DEBUG1: >+ openssh_flags = SYSLOG_LEVEL_DEBUG2; >+ break; >+ case PKCS11H_LOG_INFO: >+ openssh_flags = SYSLOG_LEVEL_INFO; >+ break; >+ case PKCS11H_LOG_WARN: >+ openssh_flags = SYSLOG_LEVEL_ERROR; >+ break; >+ case PKCS11H_LOG_ERROR: >+ openssh_flags = SYSLOG_LEVEL_FATAL; >+ break; >+ default: >+ openssh_flags = SYSLOG_LEVEL_FATAL; >+ break; >+ } >+ >+ return openssh_flags; >+} >+ >+static unsigned >+pkcs11_msg_openssh2pkcs11(const LogLevel flags) >+{ >+ unsigned pkcs11_flags; >+ >+ switch (flags) { >+ case SYSLOG_LEVEL_DEBUG3: >+ pkcs11_flags = PKCS11H_LOG_DEBUG2; >+ break; >+ case SYSLOG_LEVEL_DEBUG2: >+ pkcs11_flags = PKCS11H_LOG_DEBUG1; >+ break; >+ case SYSLOG_LEVEL_INFO: >+ pkcs11_flags = PKCS11H_LOG_INFO; >+ break; >+ case SYSLOG_LEVEL_ERROR: >+ pkcs11_flags = PKCS11H_LOG_WARN; >+ break; >+ case SYSLOG_LEVEL_FATAL: >+ pkcs11_flags = PKCS11H_LOG_ERROR; >+ break; >+ default: >+ pkcs11_flags = PKCS11H_LOG_ERROR; >+ break; >+ } >+ >+ return pkcs11_flags; >+} >+ >+/* ARGSUSED */ >+static void >+pkcs11_openssh_log(void *const global_data, unsigned flags, >+ const char *const format, va_list args) >+{ >+ do_log(pkcs11_msg_pkcs112openssh(flags), format, args); >+} >+ >+/* ARGSUSED */ >+static PKCS11H_BOOL >+pkcs11_ssh_token_prompt(void *const global_data, >+ void *const user_data, >+ const pkcs11h_token_id_t token, IN const unsigned retry) >+{ >+ return ask_permission("Please insert token '%s'", token->display); >+} >+ >+/* ARGSUSED */ >+static PKCS11H_BOOL >+_pkcs11_ssh_pin_prompt(void *const global_data, >+ void *const user_data, const pkcs11h_token_id_t token, >+ const unsigned retry, char *const pin, const size_t pin_max) >+{ >+ char prompt[1024]; >+ char *passphrase = NULL; >+ PKCS11H_BOOL ret = FALSE; >+ >+ if (snprintf(prompt, sizeof(prompt), "Please enter PIN for token '%s': ", >+ token->display) < 0) >+ goto cleanup; >+ >+ passphrase = read_passphrase(prompt, RP_ALLOW_EOF); >+ >+ if (passphrase == NULL || strlen(passphrase) == 0 || >+ strlen(passphrase) > pin_max-1) >+ goto cleanup; >+ >+ strlcpy(pin, passphrase, pin_max); >+ bzero(passphrase, strlen(passphrase)); >+ >+ ret = TRUE; >+ >+cleanup: >+ >+ if (passphrase != NULL) >+ xfree(passphrase); >+ >+ return ret; >+} >+ >+static int >+pkcs11_convert_to_ssh_key(const pkcs11h_certificate_id_t certificate_id, Key **const key, >+ char **const comment, const int pin_cache_period) >+{ >+ pkcs11h_certificate_t certificate = NULL; >+ pkcs11h_certificate_id_t certificate_id_new = NULL; >+ pkcs11h_openssl_session_t openssl_session = NULL; >+ Key *internal_key = NULL; >+ char *internal_comment = NULL; >+ RSA *rsa = NULL; >+ size_t temp; >+ CK_RV rv = CKR_OK; >+ >+ *key = NULL; >+ *comment = NULL; >+ >+ debug3("PKCS#11: pkcs11_convert_to_ssh_key - entered - certificate=%p, " >+ "key=%p, comment=%p, pin_cache_period=%d", (void *) certificate, >+ (void *) key, (void *) comment, pin_cache_period); >+ >+ if ((rv = pkcs11h_certificate_create(certificate_id, NULL, >+ PKCS11H_PROMPT_MASK_ALLOW_ALL, pin_cache_period, >+ &certificate)) != CKR_OK) { >+ error("PKCS#11: Cannot get certificate %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ /* >+ * New certificate_id is constructed from certificate >+ * blob so that it will contian the proper description. >+ */ >+ >+ if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, >+ NULL, &temp)) != CKR_OK) { >+ error("PKCS#11: Cannot get certificate blob %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ if ((rv = pkcs11h_certificate_getCertificateId(certificate, >+ &certificate_id_new)) != CKR_OK) { >+ error("PKCS#11: Cannot get certificate_id %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ if ((internal_comment = xstrdup(certificate_id_new->displayName)) == NULL) { >+ error("PKCS#11: Memory allocation error"); >+ goto cleanup; >+ } >+ >+ if ((openssl_session = >+ pkcs11h_openssl_createSession(certificate)) == NULL) { >+ error("PKCS#11: Cannot initialize openssl session"); >+ goto cleanup; >+ } >+ >+ /* >+ * will be release by openssl_session >+ */ >+ certificate = NULL; >+ >+ if ((rsa = pkcs11h_openssl_session_getRSA(openssl_session)) == NULL) { >+ error("PKCS#11: Unable get rsa object"); >+ goto cleanup; >+ } >+ >+ internal_key = key_new_private(KEY_UNSPEC); >+ internal_key->flags |= KEY_FLAG_EXT; >+ internal_key->rsa = rsa; >+ rsa = NULL; >+ internal_key->type = KEY_RSA; >+ >+ *key = internal_key; >+ internal_key = NULL; >+ *comment = internal_comment; >+ internal_comment = NULL; >+ >+cleanup: >+ if (internal_key != NULL) { >+ key_free(internal_key); >+ internal_key = NULL; >+ } >+ >+ if (internal_comment != NULL) { >+ xfree(internal_comment); >+ internal_comment = NULL; >+ } >+ >+ if (rsa != NULL) { >+ RSA_free (rsa); >+ rsa = NULL; >+ } >+ >+ if (openssl_session != NULL) { >+ pkcs11h_openssl_freeSession(openssl_session); >+ openssl_session = NULL; >+ } >+ >+ if (certificate_id_new != NULL) { >+ pkcs11h_certificate_freeCertificateId(certificate_id_new); >+ certificate_id_new = NULL; >+ } >+ >+ if (certificate != NULL) { >+ pkcs11h_certificate_freeCertificate(certificate); >+ certificate = NULL; >+ } >+ >+ debug3("PKCS#11: pkcs11_convert_to_ssh_key - return *key=%p", (void *) *key); >+ >+ return *key != NULL; >+} >+ >+int >+pkcs11_initialize(const int protected_authentication, const int pin_cache_period) >+{ >+ CK_RV rv = CKR_FUNCTION_FAILED; >+ >+ debug3("PKCS#11: pkcs11_initialize - entered protected_authentication=%d, " >+ "pin_cache_period=%d", protected_authentication, pin_cache_period); >+ >+ if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK) { >+ error("PKCS#11: Cannot set system engine %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ if ((rv = pkcs11h_initialize()) != CKR_OK) { >+ error("PKCS#11: Cannot initialize %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ if ((rv = pkcs11h_setLogHook(pkcs11_openssh_log, NULL)) != CKR_OK) { >+ error("PKCS#11: Cannot set hooks %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ pkcs11h_setLogLevel(pkcs11_msg_openssh2pkcs11(get_log_level ())); >+ >+ if ((rv = pkcs11h_setTokenPromptHook(pkcs11_ssh_token_prompt, >+ NULL)) != CKR_OK) { >+ error("PKCS#11: Cannot set hooks %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ if ((rv = pkcs11h_setPINPromptHook(_pkcs11_ssh_pin_prompt, >+ NULL)) != CKR_OK) { >+ error("PKCS#11: Cannot set hooks %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ if ((rv = pkcs11h_setProtectedAuthentication(protected_authentication)) != >+ CKR_OK) { >+ error("PKCS#11: Cannot set protected authentication mode %ld-'%s'", >+ rv, pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ if ((rv = pkcs11h_setPINCachePeriod(pin_cache_period)) != CKR_OK) { >+ error("PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ rv = CKR_OK; >+ >+cleanup: >+ debug3("PKCS#11: pkcs11_initialize - return rv=%ld-'%s'", >+ rv, pkcs11h_getMessage(rv)); >+ >+ return rv == CKR_OK; >+} >+ >+void >+pkcs11_terminate(void) >+{ >+ debug3("PKCS#11: pkcs11_terminate - entered"); >+ >+ pkcs11h_terminate(); >+ >+ debug3("PKCS#11: pkcs11_terminate - return"); >+} >+ >+void >+pkcs11_free_provider(pkcs11_provider *const provider) { >+ if (provider != NULL) { >+ if (provider->provider != NULL) >+ xfree(provider->provider); >+ xfree(provider); >+ } >+} >+ >+pkcs11_provider * >+pkcs11_parse_provider(const char *const info) >+{ >+ pkcs11_provider *provider = NULL; >+ pkcs11_provider *ret = NULL; >+ char *split[4]; >+ char *s = NULL; >+ char *p; >+ int i; >+ >+ if (info == NULL) >+ goto cleanup; >+ >+ if ((provider = (pkcs11_provider *) xmalloc(sizeof(*provider))) == NULL) >+ goto cleanup; >+ >+ memset(provider, 0, sizeof(*provider)); >+ memset(split, 0, sizeof(split)); >+ >+ if ((s=xstrdup(info)) == NULL) >+ goto cleanup; >+ >+ p = s; >+ i=0; >+ while(i<4 && p != NULL) { >+ char *t; >+ if ((t = strchr(p, ':')) != NULL) >+ *t = '\x0'; >+ split[i++] = p; >+ if (t != NULL) >+ p = t+1; >+ else >+ p = NULL; >+ } >+ >+ /* >+ * provider[:protected_authentication[:private_mode[:cert_is_private]]] >+ * string:1|0:hex:1|0 >+ */ >+ if (split[0] != NULL) >+ provider->provider = xstrdup(split[0]); >+ if (split[1] != NULL) >+ provider->protected_authentication = atoi(split[1]) != 0; >+ if (split[2] != NULL) >+ sscanf(split[2], "%x", &provider->private_mode); >+ if (split[3] != NULL) >+ provider->cert_is_private = atoi(split[3]) != 0; >+ >+ if (provider->provider == NULL || strlen(provider->provider) == 0) >+ goto cleanup; >+ >+ ret = provider; >+ provider = NULL; >+ >+cleanup: >+ if (s != NULL) >+ xfree(s); >+ >+ if (provider != NULL) >+ pkcs11_free_provider(provider); >+ >+ return ret; >+} >+ >+int >+pkcs11_add_provider(const pkcs11_provider *const provider) >+{ >+ CK_RV rv = CKR_OK; >+ >+ debug3("PKCS#11: pkcs11_add_provider - entered - provider='%s', " >+ "protected_authentication=%d, private_mode='%08x', cert_is_private=%d", >+ provider->provider, provider->protected_authentication ? 1 : 0, >+ provider->private_mode, provider->cert_is_private ? 1 : 0); >+ >+ debug("PKCS#11: Adding PKCS#11 provider '%s'", provider->provider); >+ >+ if (rv == CKR_OK && >+ (rv = pkcs11h_addProvider(provider->provider, provider->provider, >+ provider->protected_authentication, provider->private_mode, >+ PKCS11H_SLOTEVENT_METHOD_AUTO, >+ 0, provider->cert_is_private)) != CKR_OK) { >+ error("PKCS#11: Cannot initialize provider '%s' %ld-'%s'", >+ provider->provider, rv, pkcs11h_getMessage(rv)); >+ } >+ >+ debug3("PKCS#11: pkcs11_add_provider - return rv=%ld-'%s'", >+ rv, pkcs11h_getMessage(rv)); >+ >+ return rv == CKR_OK; >+} >+ >+pkcs11_id * >+pkcs11_id_new(void) >+{ >+ pkcs11_id *id = (pkcs11_id *) xmalloc(sizeof(*id)); >+ if (id != NULL) { >+ memset(id, 0, sizeof(*id)); >+ id->pin_cache_period = PKCS11H_PIN_CACHE_INFINITE; >+ } >+ return id; >+} >+ >+void >+pkcs11_id_free(pkcs11_id *const id) >+{ >+ if (id != NULL) >+ xfree(id); >+} >+ >+int >+pkcs11_get_key(const pkcs11_id *const id, Key **const key, >+ char **const comment) >+{ >+ pkcs11h_certificate_id_t certificate_id = NULL; >+ CK_RV rv = CKR_OK; >+ >+ debug3("PKCS#11: pkcs11_get_key - entered - id=%p, key=%p, " >+ "comment=%p", (const void *) id, (void *) key, (void *) comment); >+ >+ debug3("PKCS#11: pkcs11_get_key - id - id=%s, " >+ "pin_cache_period=%d, cert_file=%s", >+ id->id, id->pin_cache_period, id->cert_file); >+ >+ if (pkcs11h_certificate_deserializeCertificateId(&certificate_id, id->id)) { >+ error("PKCS#11: Cannot deserialize id %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ if (id->cert_file != NULL && id->cert_file[0] != '\x0') { >+ X509 *x509 = NULL; >+ unsigned char *p = NULL; >+ unsigned char *certificate_blob = NULL; >+ size_t certificate_blob_size = 0; >+ int size; >+ FILE *fp = NULL; >+ >+ if ((fp = fopen(id->cert_file, "r")) == NULL) { >+ error("PKCS#11: Cannot open file '%s'", id->cert_file); >+ goto cleanup1; >+ } >+ >+ if (!PEM_read_X509(fp, &x509, NULL, 0)) { >+ x509 = NULL; >+ error("PKCS#11: Cannot read PEM from file '%s'", id->cert_file); >+ goto cleanup1; >+ } >+ >+ if ((size = i2d_X509(x509, NULL)) < 0) { >+ error("PKCS#11: Cannot read decode certificate"); >+ goto cleanup1; >+ } >+ certificate_blob_size = (size_t)size; >+ >+ if ((certificate_blob = >+ (unsigned char *) xmalloc(certificate_blob_size)) == NULL) { >+ error("PKCS#11: Cannot allocate memory"); >+ goto cleanup1; >+ } >+ >+ /* >+ * i2d_X509 increments p!!! >+ */ >+ p = certificate_blob; >+ >+ if ((size = i2d_X509(x509, &p)) < 0) { >+ error("PKCS#11: Cannot read decode certificate"); >+ goto cleanup1; >+ } >+ certificate_blob_size = (size_t)size; >+ >+ if (pkcs11h_certificate_setCertificateIdCertificateBlob >+ (certificate_id, certificate_blob, certificate_blob_size) >+ != CKR_OK) { >+ error("PKCS#11: Cannot set certificate blob %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup1; >+ } >+ >+ cleanup1: >+ if (x509 != NULL) { >+ X509_free(x509); >+ x509 = NULL; >+ } >+ >+ if (certificate_blob != NULL) { >+ xfree(certificate_blob); >+ certificate_blob = NULL; >+ } >+ >+ if (fp != NULL) { >+ fclose(fp); >+ fp = NULL; >+ } >+ } >+ >+ pkcs11_convert_to_ssh_key(certificate_id, key, comment, id->pin_cache_period); >+ >+cleanup: >+ >+ if (certificate_id != NULL) { >+ pkcs11h_certificate_freeCertificateId(certificate_id); >+ certificate_id = NULL; >+ } >+ >+ debug3("PKCS#11: pkcs11_get_key - return rv=%ld, *key=%p", rv, ( void *) *key); >+ >+ return *key != NULL; >+} >+ >+int >+pkcs11_get_keys(Key ***const keys, char ***const comments) >+{ >+#define PKCS11_MAX_KEYS 10 >+ Key **internal_keys = NULL; >+ char **internal_comments = NULL; >+ pkcs11h_certificate_id_list_t user_certificates = NULL; >+ pkcs11h_certificate_id_list_t current = NULL; >+ CK_RV rv = CKR_FUNCTION_FAILED; >+ int i; >+ >+ debug3("PKCS#11: pkcs11_get_keys - entered - sshkey=%p, " >+ "comment=%p", >+ (void *) keys, (void *) comments); >+ >+ *keys = NULL; >+ *comments = NULL; >+ >+ if((internal_keys = (Key **) xcalloc(sizeof(*internal_keys), PKCS11_MAX_KEYS+1)) == NULL) { >+ rv = CKR_HOST_MEMORY; >+ goto cleanup; >+ } >+ >+ if((internal_comments = (char **) xcalloc(sizeof(*internal_comments), PKCS11_MAX_KEYS+1)) == NULL) { >+ rv = CKR_HOST_MEMORY; >+ goto cleanup; >+ } >+ >+ memset(internal_keys, 0, (PKCS11_MAX_KEYS+1)*sizeof(*internal_keys)); >+ memset(internal_comments, 0, (PKCS11_MAX_KEYS+1)*sizeof(*internal_comments)); >+ >+ if ((rv = pkcs11h_certificate_enumCertificateIds( >+ PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL, >+ PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, >+ &user_certificates)) != CKR_OK) { >+ error("PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ i = 0; >+ for (current = user_certificates; current != NULL && i<PKCS11_MAX_KEYS; >+ current = current->next) { >+ >+ if (pkcs11_convert_to_ssh_key(current->certificate_id, &internal_keys[i], >+ &internal_comments[i], PKCS11H_PIN_CACHE_INFINITE)) { >+ i++; >+ } >+ } >+ >+ *keys = internal_keys; >+ internal_keys = NULL; >+ *comments = internal_comments; >+ internal_comments = NULL; >+ rv = CKR_OK; >+ >+cleanup: >+ if (user_certificates != NULL) { >+ pkcs11h_certificate_freeCertificateIdList(user_certificates); >+ user_certificates = NULL; >+ } >+ >+ if (internal_keys != NULL) { >+ Key **t = internal_keys; >+ while (*t != NULL) { >+ key_free(*t); >+ t++; >+ } >+ xfree(internal_keys); >+ } >+ >+ if (internal_comments != NULL) { >+ char **t = internal_comments; >+ while (*t != NULL) { >+ xfree(*t); >+ t++; >+ } >+ xfree(internal_comments); >+ } >+ >+ debug3("PKCS#11: pkcs11_get_keys - return rv=%ld, *keys=%p", rv, (void *) *keys); >+ >+ return *keys != NULL; >+#undef PKCS11_MAX_KEYS >+} >+ >+void >+pkcs11_show_ids(void) >+{ >+ pkcs11h_certificate_id_list_t user_certificates = NULL; >+ pkcs11h_certificate_id_list_t current = NULL; >+ CK_RV rv = CKR_FUNCTION_FAILED; >+ >+ if ((rv = pkcs11h_certificate_enumCertificateIds( >+ PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL, >+ PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, >+ &user_certificates)) != CKR_OK) { >+ error("PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup; >+ } >+ >+ for (current = user_certificates; current != NULL; >+ current = current->next) { >+ >+ pkcs11h_certificate_t certificate = NULL; >+ X509 *x509 = NULL; >+ >+ BIO *bio = NULL; >+ char dn[1024] = { 0 }; >+ char serial[1024] = { 0 }; >+ char *ser = NULL; >+ char *ssh_key = NULL; >+ size_t ser_len = 0; >+ int n; >+ >+ if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, >+ &ser_len, current->certificate_id)) != CKR_OK) { >+ error("PKCS#11: Cannot serialize certificate id " >+ "certificates %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup1; >+ } >+ >+ if ((ser = (char *) xmalloc(ser_len)) == NULL) { >+ error("PKCS#11: Cannot allocate memory"); >+ goto cleanup1; >+ } >+ >+ if ((rv = pkcs11h_certificate_serializeCertificateId(ser, >+ &ser_len, current->certificate_id)) != CKR_OK) { >+ error("PKCS#11: Cannot serialize certificate " >+ "id certificates %ld-'%s'", >+ rv, pkcs11h_getMessage(rv)); >+ goto cleanup1; >+ } >+ >+ if ((rv = pkcs11h_certificate_create(current->certificate_id, >+ NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, >+ PKCS11H_PIN_CACHE_INFINITE, &certificate)) != CKR_OK) { >+ error("PKCS#11: Cannot create certificate %ld-'%s'", rv, >+ pkcs11h_getMessage(rv)); >+ goto cleanup1; >+ } >+ >+ if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL) { >+ error("PKCS#11: Cannot get X509"); >+ goto cleanup1; >+ } >+ >+ X509_NAME_oneline(X509_get_subject_name(x509), dn, sizeof(dn)); >+ >+ if ((bio = BIO_new(BIO_s_mem())) == NULL) { >+ error("PKCS#11: Cannot create BIO"); >+ goto cleanup1; >+ } >+ >+ i2a_ASN1_INTEGER(bio, X509_get_serialNumber(x509)); >+ n = BIO_read(bio, serial, sizeof(serial) - 1); >+ if (n < 0) >+ serial[0] = '\x0'; >+ else >+ serial[n] = 0; >+ >+ printf(("\n" >+ "********************************************\n" >+ "IDENTITY:\n" >+ " DN: %s\n" >+ " Serial: %s\n" >+ " Serialized id: %s\n" >+ "\n" " Certificate:\n"), dn, serial, ser); >+ PEM_write_X509(stdout, x509); >+ >+ if ((ssh_key = ssh_from_x509(x509)) != NULL) { >+ printf(("\n" " SSH:\n" "%s\n"), ssh_key); >+ >+ xfree(ssh_key); >+ } >+ >+ cleanup1: >+ if (x509 != NULL) { >+ X509_free(x509); >+ x509 = NULL; >+ } >+ >+ if (bio != NULL) { >+ BIO_free_all(bio); >+ bio = NULL; >+ } >+ >+ if (certificate != NULL) { >+ pkcs11h_certificate_freeCertificate(certificate); >+ certificate = NULL; >+ } >+ >+ if (ser != NULL) { >+ xfree(ser); >+ ser = NULL; >+ } >+ } >+ >+cleanup: >+ if (user_certificates != NULL) { >+ pkcs11h_certificate_freeCertificateIdList(user_certificates); >+ user_certificates = NULL; >+ } >+} >+ >+static char * >+ssh_from_x509(X509 * x509) >+{ >+ Buffer b; >+ EVP_PKEY *pubkey = NULL; >+ char *ret = NULL; >+ size_t retsize = 0; >+ const char *keyname = "ssh-rsa"; >+ int ok = 0; >+ >+ buffer_init(&b); >+ >+ if ((pubkey = X509_get_pubkey(x509)) == NULL) >+ goto cleanup; >+ >+ if (pubkey->type != EVP_PKEY_RSA) >+ goto cleanup; >+ >+ buffer_put_cstring(&b, keyname); >+ buffer_put_bignum2(&b, pubkey->pkey.rsa->e); >+ buffer_put_bignum2(&b, pubkey->pkey.rsa->n); >+ >+ /* be on the safe side, each byte=4 + 4 suffix + null terminate + keyname */ >+ retsize = buffer_len(&b)*4+4+1+strlen(keyname)+1; >+ if ((ret = (char *) xmalloc(retsize)) == NULL) >+ goto cleanup; >+ snprintf(ret, retsize, "%s ", keyname); >+ if (uuencode(buffer_ptr(&b), buffer_len(&b), ret+strlen(ret), retsize-strlen(ret)) == -1) >+ goto cleanup; >+ >+ ok = 1; >+ >+cleanup: >+ >+ if (pubkey != NULL) { >+ EVP_PKEY_free(pubkey); >+ pubkey = NULL; >+ } >+ >+ buffer_free(&b); >+ >+ if (!ok) { >+ if (ret != NULL) { >+ xfree(ret); >+ ret = NULL; >+ } >+ } >+ >+ return ret; >+} >+ >+#endif /* ENABLE_PKCS11 */ >diff -urNp ssh/pkcs11.h ssh.new/pkcs11.h >--- ssh/pkcs11.h 1970-01-01 02:00:00.000000000 +0200 >+++ ssh.new/pkcs11.h 2008-04-26 23:52:57.000000000 +0300 >@@ -0,0 +1,77 @@ >+/* >+ * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR >+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES >+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. >+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, >+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT >+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef SSH_PKCS11_H >+#define SSH_PKCS11_H >+ >+#ifdef ENABLE_PKCS11 >+ >+#include "key.h" >+ >+typedef struct { >+ char *provider; >+ int protected_authentication; >+ unsigned private_mode; >+ int cert_is_private; >+} pkcs11_provider; >+ >+typedef struct { >+ char *id; >+ int pin_cache_period; >+ char *cert_file; >+} pkcs11_id; >+ >+int >+pkcs11_initialize(const int, const int); >+ >+void >+pkcs11_terminate(void); >+ >+void >+pkcs11_free_provider(pkcs11_provider *const); >+ >+pkcs11_provider * >+pkcs11_parse_provider(const char *const); >+ >+int >+pkcs11_add_provider(const pkcs11_provider *const); >+ >+pkcs11_id * >+pkcs11_id_new(void); >+ >+void >+pkcs11_id_free(pkcs11_id *const); >+ >+int >+pkcs11_get_key(const pkcs11_id *const, Key **const, char **const); >+ >+int >+pkcs11_get_keys(Key ***const, char ***const); >+ >+void >+pkcs11_show_ids(void); >+ >+#endif /* ENABLE_PKCS11 */ >+ >+#endif /* OPENSSH_PKCS11_H */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1371
:
1444
|
1463
|
1464
|
1465
|
1466
|
1467
|
1468
|
1469
|
1470
|
1471
|
1477
|
1478
|
1484
|
1485
|
1486
|
1487
|
1488
|
1489
|
1490
|
1491
|
1492
|
1493
|
1494
|
1495
|
1496
|
1497
|
1547
|
1557
|
1558