/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* p11-rpc-util.c - utilities for module and dispatcher Copyright (C) 2008, Stef Walter The Gnome Keyring Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The Gnome Keyring Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the Gnome Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Author: Stef Walter <stef@memberwebs.com> */ #include "config.h" #include "gck-rpc-layer.h" #include "gck-rpc-private.h" #include <stdarg.h> #include <string.h> #include <stdio.h> static void do_log(const char *pref, const char *msg, va_list va) { char buffer[1024]; size_t len = 0; if (pref) { snprintf(buffer, sizeof(buffer), "%s: ", pref); len = strlen(buffer); } vsnprintf(buffer + len, sizeof(buffer) - len, msg, va); gck_rpc_log(buffer); } void gck_rpc_warn(const char *msg, ...) { va_list va; va_start(va, msg); do_log("WARNING", msg, va); va_end(va); } void gck_rpc_debug(const char *msg, ...) { va_list va; va_start(va, msg); do_log("DEBUG", msg, va); va_end(va); } int gck_rpc_mechanism_is_supported(CK_MECHANISM_TYPE mech) { if (gck_rpc_mechanism_has_no_parameters(mech) || gck_rpc_mechanism_has_sane_parameters(mech)) return 1; return 0; } void gck_rpc_mechanism_list_purge(CK_MECHANISM_TYPE_PTR mechs, CK_ULONG * n_mechs) { int i; assert(mechs); assert(n_mechs); for (i = 0; i < (int)(*mechs); ++i) { if (!gck_rpc_mechanism_has_no_parameters(mechs[i]) && !gck_rpc_mechanism_has_sane_parameters(mechs[i])) { /* Remove the mechanism from the list */ memmove(&mechs[i], &mechs[i + 1], (*n_mechs - i) * sizeof(CK_MECHANISM_TYPE)); --(*n_mechs); --i; } } } int gck_rpc_mechanism_has_sane_parameters(CK_MECHANISM_TYPE type) { /* This list is incomplete */ switch (type) { case CKM_RSA_PKCS_OAEP: case CKM_RSA_PKCS_PSS: return 1; default: return 0; } } int gck_rpc_mechanism_has_no_parameters(CK_MECHANISM_TYPE mech) { /* This list is incomplete */ switch (mech) { case CKM_RSA_PKCS_KEY_PAIR_GEN: case CKM_RSA_X9_31_KEY_PAIR_GEN: case CKM_RSA_PKCS: case CKM_RSA_9796: case CKM_RSA_X_509: case CKM_RSA_X9_31: case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: case CKM_SHA256_RSA_PKCS: case CKM_SHA384_RSA_PKCS: case CKM_SHA512_RSA_PKCS: case CKM_RIPEMD128_RSA_PKCS: case CKM_RIPEMD160_RSA_PKCS: case CKM_SHA1_RSA_X9_31: case CKM_DSA_KEY_PAIR_GEN: case CKM_DSA_PARAMETER_GEN: case CKM_DSA: case CKM_DSA_SHA1: case CKM_FORTEZZA_TIMESTAMP: case CKM_EC_KEY_PAIR_GEN: case CKM_ECDSA: case CKM_ECDSA_SHA1: case CKM_DH_PKCS_KEY_PAIR_GEN: case CKM_DH_PKCS_PARAMETER_GEN: case CKM_X9_42_DH_KEY_PAIR_GEN: case CKM_X9_42_DH_PARAMETER_GEN: case CKM_KEA_KEY_PAIR_GEN: case CKM_GENERIC_SECRET_KEY_GEN: case CKM_RC2_KEY_GEN: case CKM_RC4_KEY_GEN: case CKM_RC4: case CKM_RC5_KEY_GEN: case CKM_AES_KEY_GEN: case CKM_AES_ECB: case CKM_AES_MAC: case CKM_DES_KEY_GEN: case CKM_DES2_KEY_GEN: case CKM_DES3_KEY_GEN: case CKM_CDMF_KEY_GEN: case CKM_CAST_KEY_GEN: case CKM_CAST3_KEY_GEN: case CKM_CAST128_KEY_GEN: case CKM_IDEA_KEY_GEN: case CKM_SSL3_PRE_MASTER_KEY_GEN: case CKM_TLS_PRE_MASTER_KEY_GEN: case CKM_SKIPJACK_KEY_GEN: case CKM_BATON_KEY_GEN: case CKM_JUNIPER_KEY_GEN: case CKM_RC2_ECB: case CKM_DES_ECB: case CKM_DES3_ECB: case CKM_CDMF_ECB: case CKM_CAST_ECB: case CKM_CAST3_ECB: case CKM_CAST128_ECB: case CKM_RC5_ECB: case CKM_IDEA_ECB: case CKM_RC2_MAC: case CKM_DES_MAC: case CKM_DES3_MAC: case CKM_CDMF_MAC: case CKM_CAST_MAC: case CKM_CAST3_MAC: case CKM_RC5_MAC: case CKM_IDEA_MAC: case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: case CKM_SKIPJACK_WRAP: case CKM_BATON_WRAP: case CKM_JUNIPER_WRAP: case CKM_MD2: case CKM_MD2_HMAC: case CKM_MD5: case CKM_MD5_HMAC: case CKM_SHA_1: case CKM_SHA_1_HMAC: case CKM_SHA256: case CKM_SHA256_HMAC: case CKM_SHA384: case CKM_SHA384_HMAC: case CKM_SHA512: case CKM_SHA512_HMAC: case CKM_FASTHASH: case CKM_RIPEMD128: case CKM_RIPEMD128_HMAC: case CKM_RIPEMD160: case CKM_RIPEMD160_HMAC: case CKM_KEY_WRAP_LYNKS: return 1; default: return 0; }; } int gck_rpc_has_ulong_parameter(CK_ATTRIBUTE_TYPE type) { switch (type) { case CKA_CLASS: case CKA_KEY_TYPE: case CKA_CERTIFICATE_TYPE: case CKA_HW_FEATURE_TYPE: return 1; default: return 0; } } int gck_rpc_has_bad_sized_ulong_parameter(CK_ATTRIBUTE_PTR attr) { if (!attr->pValue) return 0; /* All this parameters are transmited on the network * as 64bit integers */ if (sizeof (uint64_t) != attr->ulValueLen) return 0; if (sizeof (CK_ULONG) == attr->ulValueLen) return 0; return gck_rpc_has_ulong_parameter(attr->type); } /* * Parses prefix into two strings (host and port). Port may be a NULL pointer * if none is specified. Since this code does not decode port in any way, a * service name works too (but requires other code (like * _get_listening_socket()) able to resolve service names). * * This should work for IPv4 and IPv6 inputs : * * 0.0.0.0:2345 * 0.0.0.0 * [::]:2345 * [::] * [::1]:2345 * localhost:2345 * localhost * localhost:p11proxy (if p11proxy is a known service name) * * Returns 0 on failure, and 1 on success. */ int gck_rpc_parse_host_port(const char *prefix, char **host, char **port) { char *p = NULL; int is_ipv6; is_ipv6 = (prefix[0] == '[') ? 1 : 0; *host = strdup(prefix + is_ipv6); *port = NULL; if (*host == NULL) { gck_rpc_warn("out of memory"); return 0; } if (is_ipv6 && prefix[0] == '[') p = strchr(*host, ']'); else p = strchr(*host, ':'); if (p) { is_ipv6 = (*p == ']'); /* remember if separator was ']' */ *p = '\0'; /* replace separator will NULL to terminate *host */ *port = p + 1; if (is_ipv6 && (**port == ':')) *port = p + 2; } return 1; }