Current File : //usr/include/cryptoutil.h
/*
 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef _CRYPTOUTIL_H
#define	_CRYPTOUTIL_H

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <syslog.h>
#include <security/cryptoki.h>
#include <sys/param.h>
#include <sys/paths.h>

#define	LOG_STDERR	-1	/* cryptoerror() log to stderr, not syslog */
#define	SUCCESS		0
#define	FAILURE		1
#define	MECH_ID_HEX_LEN	11	/* length of mechanism id in hex form */

#define	_PATH_PKCS11_CONF	"/etc/crypto/pkcs11.conf"
#define	_PATH_KCF_CONF		"/etc/crypto/kcf.conf"
#define	_PATH_KCFD_LOCK		_PATH_SYSVOL "/kcfd.lock"

#define	BYTES_IN_WORD	4

/* $ISA substitution for parsing pkcs11.conf data */
#define	PKCS11_ISA	"/$ISA/"
#if	defined(_LP64)
#if	defined(__sparcv9)
#define	PKCS11_ISA_DIR		"/sparcv9/"
#elif	defined(__amd64)
#define	PKCS11_ISA_DIR		"/amd64/"
#else
#define	PKCS11_ISA_DIR		"/64/"
#endif
#else	/* 32-bit */
#define	PKCS11_ISA_DIR		"/"
#endif	/* _LP64 */

/* keywords and delimiters for parsing configuration files */
#define	SEP_COLON			":"
#define	SEP_SEMICOLON			";"
#define	SEP_EQUAL			"="
#define	SEP_COMMA			","
#define	METASLOT_KEYWORD		"metaslot"
#define	FIPS_KEYWORD			"fips-140"
#define	EF_DISABLED			"disabledlist="
#define	EF_ENABLED			"enabledlist="
#define	EF_NORANDOM			"NO_RANDOM"
#define	METASLOT_TOKEN			"metaslot_token="
#define	METASLOT_SLOT			"metaslot_slot="
#define	METASLOT_STATUS			"metaslot_status="
#define	METASLOT_AUTO_KEY_MIGRATE	"metaslot_auto_key_migrate="
#define	ENABLED_KEYWORD			"enabled"
#define	DISABLED_KEYWORD		"disabled"

/*
 * These should eventually be subsumed by sys/crypto/common.h
 */
#define	SLOT_DESCRIPTION_SIZE		64
#define	TOKEN_LABEL_SIZE		32
#define	TOKEN_MANUFACTURER_SIZE		32
#define	TOKEN_SERIAL_SIZE		16

/*
 * Define the following softtoken and metaslot string values that are shared
 * by softtoken library, cryptoadm and pktool command.
 */

#define	SOFT_SLOT_DESCRIPTION	\
			"Sun Crypto Softtoken            " \
			"                                "
#define	SOFT_TOKEN_LABEL	"Sun Software PKCS#11 softtoken  "
#define	SOFT_TOKEN_SERIAL	"                "
#define	SOFT_MANUFACTURER_ID	"Oracle Corporation              "
#define	SOFT_DEFAULT_PIN	"changeme"

#define	METASLOT_FRAMEWORK_ID	0
#define	METASLOT_SLOT_DESCRIPTION \
			"Sun Metaslot                    " \
			"                                "
#define	METASLOT_TOKEN_LABEL	"Sun Metaslot                    "
#define	METASLOT_TOKEN_SERIAL	"                "
#define	METASLOT_MANUFACTURER_ID \
				"Oracle Corporation              "

/* Default values used by crypto_get_pass() */
#define	MAX_PASS_BUFFER		1024	/* from prompts and message strings */
#define	MIN_PASS_LENGTH		8	/* minimum passphrase length */
#define	MAX_PASS_TRIES		5	/* maximum tries to get passphrase */

/* Standardized strings for crypto_get_pass() for token PINs */
#define	DEFAULT_TOKEN_PROMPT	gettext("Enter PIN for %s: ")
#define	DEFAULT_TOKEN_REPROMPT	gettext("Re-enter PIN for %s: ")
#define	DEFAULT_TOKEN_MINSIZE	\
		gettext("PIN must be at least %ld characters.\n")
#define	DEFAULT_TOKEN_MAXTRIES	gettext("Exceeded number of attempts.\n")

/* Standardized (and default) strings for crypto_get_pass() for passphrases */
#define	DEFAULT_USER_PROMPT	gettext("Enter passphrase: ")
#define	DEFAULT_USER_REPROMPT	gettext("Re-enter passphrase: ")
#define	DEFAULT_USER_MINSIZE	\
		gettext("Passphrase must be at least %ld characters.\n")
#define	DEFAULT_USER_MAXTRIES	gettext("Exceeded number of attempts.\n")

/*
 * Flag type for pkcs11_flag2str() and pkcs11_flags2str()
 * Note: We ignore CKF_DONT_BLOCK and CKF_ARRAY_ATTRIBUTE which are specific.
 */
#define	PK11_FL_LIB		0
#define	PK11_FL_SLOT		1
#define	PK11_FL_TOKEN		2
#define	PK11_FL_SESSION		3
#define	PK11_FL_MECH		4
#define	PK11_FL_OTP		5

typedef char libname_t[MAXPATHLEN];
typedef char midstr_t[MECH_ID_HEX_LEN];

typedef struct umechlist {
	midstr_t		name;	/* mechanism name in hex form */
	struct umechlist	*next;
} umechlist_t;

typedef struct uentry {
	libname_t	name;
	boolean_t	flag_norandom; /* TRUE if random is disabled */
	boolean_t	flag_enabledlist; /* TRUE if an enabledlist */
	umechlist_t	*policylist; /* disabledlist or enabledlist */
	boolean_t	flag_metaslot_enabled; /* TRUE if metaslot's enabled */
	boolean_t	flag_metaslot_auto_key_migrate;
	CK_UTF8CHAR	metaslot_ks_slot[SLOT_DESCRIPTION_SIZE + 1];
	CK_UTF8CHAR	metaslot_ks_token[TOKEN_LABEL_SIZE + 1];
	int		count;
} uentry_t;

typedef struct uentrylist {
	uentry_t	*puent;
	struct uentrylist	*next;
} uentrylist_t;

/* Integer represented as a big-endian byte string */
typedef struct biginteger {
	uchar_t	*big_value;
	ulong_t	big_value_len;
} biginteger_t;

/* Return codes for pkcs11_parse_uri() */
#define	PK11_URI_OK		0
#define	PK11_URI_INVALID	1
#define	PK11_MALLOC_ERROR	2
#define	PK11_URI_VALUE_OVERFLOW	3
#define	PK11_NOT_PKCS11_URI	4

/*
 * There is no limit for the attribute length in the spec. 256 bytes should be
 * enough for the object name.
 */
#define	PK11_MAX_OBJECT_LEN		256
/*
 * CKA_ID is of type "byte array" which can be of arbitrary length. 256 bytes
 * should be sufficient though.
 */
#define	PK11_MAX_ID_LEN			256

/* Maximum /etc/crypto/ configuration file line length */
#define	CONFLINE_MAX_LEN		4096

/* Structure for the PKCS#11 URI. */
typedef struct pkcs11_uri_t {
	/* CKA_LABEL attribute to the C_FindObjectsInit function. */
	CK_UTF8CHAR_PTR	object;
	/*
	 * CKA_CLASS attribute to the C_FindObjectsInit function. The
	 * "objecttype" URI attribute can have a value one of "private",
	 * "public", "cert", "secretkey", and "data". The "objecttype" field can
	 * have a value of CKO_PUBLIC_KEY, CKO_PRIVATE_KEY, CKO_CERTIFICATE,
	 * CKO_SECRET_KEY, and CKO_DATA. This attribute cannot be empty in the
	 * URI.
	 */
	CK_ULONG	objecttype;
	/* CKO_DATA is 0 so we need this flag. Not part of the URI itself. */
	boolean_t	objecttype_present;
	/*
	 * Token, manufacturer, serial and model are of fixed size length in
	 * the specification. We allocate memory on the fly to distinguish
	 * between an attribute not present and an empty value. We check for
	 * overflows. We always terminate the string with '\0' even when that is
	 * not used in the PKCS#11's CK_TOKEN_INFO structure (fields are padded
	 * with spaces).
	 */
	/* Token label from CK_TOKEN_INFO. */
	CK_UTF8CHAR_PTR	token;
	/* ManufacturerID from CK_TOKEN_INFO. */
	CK_UTF8CHAR_PTR	manuf;
	/* SerialNumber from CK_TOKEN_INFO. */
	CK_CHAR_PTR	serial;
	/* Model from CK_TOKEN_INFO. */
	CK_UTF8CHAR_PTR	model;
	/* This is a byte array, we need a length parameter as well. */
	CK_BYTE_PTR	id;
	int		id_len;
	/*
	 * Location of the file with a token PIN. Application can overload this,
	 * eg. "/bin/askpass|" may mean to read the PIN from a command. However,
	 * the pkcs11_parse_uri() function does not interpret this field in any
	 * way.
	 */
	char		*pinfile;
} pkcs11_uri_t;

/* PRINTFLIKE1 */
extern void cryptodebug(const char *fmt, ...);
/* PRINTFLIKE2 */
extern void cryptoerror(int priority, const char *fmt, ...);
extern void cryptodebug_init(const char *prefix);
extern void cryptoerror_off(void);
extern void cryptoerror_on(void);

extern const char *pkcs11_attr2str(CK_ATTRIBUTE_TYPE attr);
extern CK_RV pkcs11_str2attr(const char *attr_str, CK_ATTRIBUTE_TYPE *attr);
extern const char *pkcs11_flag2str(int fl_type, CK_FLAGS flag);
extern char *pkcs11_flags2str(int fl_type, CK_FLAGS flags,
    const char *separator);
extern CK_RV pkcs11_str2flag(int fl_type, const char *flag_str,
    CK_FLAGS *flag);
extern CK_RV pkcs11_str2flags(int fl_type, const char *flags_str,
    CK_FLAGS *flags, const char *separator);
extern const char *pkcs11_hwftype2str(CK_HW_FEATURE_TYPE hw_feature);
extern CK_RV pkcs11_str2hwftype(const char *attr_str,
    CK_HW_FEATURE_TYPE *hw_feature);
extern const char *pkcs11_mech2str(CK_MECHANISM_TYPE mech);
extern CK_RV pkcs11_str2mech(const char *mech_str, CK_MECHANISM_TYPE_PTR mech);
extern const char *pkcs11_keytype2str(CK_KEY_TYPE key_type);
extern CK_RV pkcs11_str2keytype(const char *keytype_str, CK_KEY_TYPE *key_type);
extern const char *pkcs11_objclass2str(CK_OBJECT_CLASS obj_type);
extern CK_RV pkcs11_str2objclass(const char *objclass_str,
    CK_OBJECT_CLASS *obj_class);
extern const char *pkcs11_retval2str(CK_RV retval);
extern CK_RV pkcs11_str2retval(const char *retval_str, CK_RV *retval);
extern const char *pkcs11_state2str(CK_STATE state);
extern CK_RV pkcs11_str2state(const char *state_str, CK_STATE *state);
extern const char *pkcs11_usertype2str(CK_USER_TYPE user_type);
extern CK_RV pkcs11_str2usertype(const char *usertype_str,
    CK_USER_TYPE *user_type);

extern int get_pkcs11conf_info(uentrylist_t **ppliblist);
extern umechlist_t *create_umech(char *name);
extern void free_umechlist(umechlist_t *plist);
extern void free_uentrylist(uentrylist_t *entrylist);
extern void free_uentry(uentry_t *pent);
extern uentry_t *getent_uef(char *libname);

extern void tohexstr(const uchar_t *bytes, size_t blen, char *hexstr,
    size_t hexlen);
extern int hexstr_to_bytes(const char *hexstr, size_t hexlen, uchar_t **bytes,
    size_t *blen);
extern CK_RV pkcs11_mech2keytype(CK_MECHANISM_TYPE mech_type,
    CK_KEY_TYPE *ktype);
extern CK_RV pkcs11_mech2keygen(CK_MECHANISM_TYPE mech_type,
    CK_MECHANISM_TYPE *gen_mech);

extern char *pkcs11_strerror(CK_RV rv);

extern int
get_metaslot_info(boolean_t  *status_enabled, boolean_t *migrate_enabled,
    char **objectstore_slot_info, char **objectstore_token_info);

extern char *get_fullpath(char *dir, char *filepath);
extern int str2lifetime(char *ltimestr, uint32_t *ltime);

extern char *pkcs11_default_token(void);
extern int pkcs11_get_pass(char *token_name, char **pdata, size_t *psize,
    size_t min_psize, boolean_t with_confirmation);
extern int crypto_get_pass(char *prompt, char *confirm, size_t min_psize,
    char *too_short, uint8_t max_tries, char *limit_reached, char **pdata,
    size_t *psize);

extern int crypto_read_file(char *filename, void **dbuf, size_t *dlen);

extern int open_nointr(const char *path, int oflag, ...);
extern ssize_t readn_nointr(int fd, void *dbuf, size_t dlen);
extern ssize_t writen_nointr(int fd, void *dbuf, size_t dlen);

extern int update_conf(char *conf_file, char *entry);

extern CK_RV get_conf_value(char *provider, char *param, char **value,
    char *buffer, size_t buffer_size);

extern int pkcs11_parse_uri(const char *str, pkcs11_uri_t *uri);
extern void pkcs11_free_uri(pkcs11_uri_t *uri);

extern int memcmp_pad_max(void *d1, uint_t d1_len, void *d2,
    uint_t d2_len, uint_t max_sz);

extern char *trim_trailing_whitespace(char *buf, const size_t maxlen);

extern void bigint_move(biginteger_t *src, biginteger_t *dst);

extern int bigint_bitlen(biginteger_t *bigint);

extern void bigint_cleanup(biginteger_t *big);

extern int bigint_init(biginteger_t *bi, uchar_t *buf, ulong_t buflen);

extern int bigint_pad(biginteger_t *src, biginteger_t *dst);

extern int bigint_unpad(biginteger_t src, biginteger_t *dst);

extern int bigint_copy(biginteger_t *new_bigint, biginteger_t *old_bigint);

extern int bigint_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR pAttr);

extern int bigint_to_template(biginteger_t *big, CK_ATTRIBUTE_PTR pAttr);

extern int check_ucf_libs(const char *caller);

#ifdef __cplusplus
}
#endif

#endif /* _CRYPTOUTIL_H */