/* src/scep.h */ #ifndef SCEP_H_ #define SCEP_H_ #include #include #include #include #include #include #include #include #include #include #ifndef OPENSSL_NO_ENGINE #include #endif /* OPENSSL_NO_ENGINE */ #define DEFAULT_SIGALG EVP_md5() #define DEFAULT_ENCALG EVP_des_cbc() #define DEFAULT_VERBOSITY ERROR #define libscep_VERSION_MAJOR @libscep_VERSION_MAJOR@ #define libscep_VERSION_MINOR @libscep_VERSION_MINOR@ #define libscep_STR(x) #x #define libscep_VERSION_STR(major, minor) "scep-client v" libscep_STR(major) "." libscep_STR(minor) #define SCEP_MSG_PKCSREQ_STR "19" #define SCEP_MSG_CERTREP_STR "3" #define SCEP_MSG_GETCERTINITIAL_STR "20" #define SCEP_MSG_GETCERT_STR "21" #define SCEP_MSG_GETCRL_STR "22" #define SCEP_PKISTATUS_SUCCESS "0" #define SCEP_PKISTATUS_FAILURE "2" #define SCEP_PKISTATUS_PENDING "3" #define SCEP_BAD_ALG_NR "0" #define SCEP_BAD_MESSAGE_CHECK_NR "1" #define SCEP_BAD_REQUEST_NR "2" #define SCEP_BAD_TIME_NR "3" #define SCEP_BAD_CERT_ID_NR "4" // number of nonce bytes, defined by protocol #define NONCE_LENGTH 16 #define SCEP_SELFSIGNED_EXPIRE_DAYS 7 #define SCEP_MIME_GETCA_RA "application/x-x509-ca-ra-cert" #define SCEP_MIME_GETCA "application/x-x509-ca-cert" #define scep_log(handle, verbosity, format, ...) \ _scep_log(handle, verbosity, __FILE__, __LINE__, format, ##__VA_ARGS__) #define SCEP_ERR(type, msg, ...) \ do { \ error = type; \ if(msg) \ scep_log(handle, FATAL, msg, ##__VA_ARGS__);\ goto finally; \ } while(0) #define OSSL_ERR(msg, ...) \ do { \ ERR_print_errors(handle->configuration->log); \ SCEP_ERR(SCEPE_OPENSSL, msg, ##__VA_ARGS__); \ } while(0) typedef enum { FATAL, ERROR, WARN, INFO, DEBUG, } SCEP_VERBOSITY; typedef enum { /* Global options */ SCEPCFG_VERBOSITY, SCEPCFG_SIGALG, SCEPCFG_ENCALG, SCEPCFG_LOG, #ifndef OPENSSL_NO_ENGINE /* Engine stuff */ SCEPCFG_ENGINE, SCEPCFG_ENGINE_OBJ, SCEPCFG_ENGINE_PARAM, #endif /* OPENSSL_NO_ENGINE */ /* Flags to be set */ SCEPCFG_FLAG_CLEAR, // clear all flags SCEPCFG_FLAG_SET, } SCEPCFG_TYPE; typedef enum { SCEPE_OK, SCEPE_MEMORY, SCEPE_UNKNOWN_CONFIGURATION, SCEPE_UNKOWN_OPERATION, SCEPE_DUPLICATE_BIO, SCEPE_PROTOCOL, SCEPE_INVALID_CONTENT, SCEPE_INVALID_PARAMETER, SCEPE_UNHANDLED, SCEPE_PARAM, SCEPE_NYI, SCEPE_OPENSSL, SCEPE_INTERNAL, // this always needs to be the last error for unit tests. It is used to // make sure we test all error messages. SCEPE_DUMMY_LAST_ERROR, } SCEP_ERROR; typedef enum { SCEPOP_NONE, SCEPOP_GETCACERT, SCEPOP_PKCSREQ, SCEPOP_GETCERT, SCEPOP_GETCRL, SCEPOP_GETNEXTCACERT, SCEPOP_GETCERTINITIAL, SCEPOP_CERTREP, } SCEP_OPERATION; typedef enum { SCEP_SUCCESS = 0, SCEP_FAILURE = 2, SCEP_PENDING = 3, } SCEP_PKISTATUS; typedef enum { SCEP_BAD_ALG = 0, SCEP_BAD_MESSAGE_CHECK = 1, SCEP_BAD_REQUEST = 2, SCEP_BAD_TIME = 3, SCEP_BAD_CERT_ID = 4, } SCEP_FAILINFO; typedef enum { SCEP_MSG_PKCSREQ = 19, SCEP_MSG_CERTREP = 3, SCEP_MSG_GETCERTINITIAL = 20, SCEP_MSG_GETCERT = 21, SCEP_MSG_GETCRL = 22, } SCEP_MESSAGE_TYPE; typedef enum { SCEP_SKIP_SIGNER_CERT = 0x0001, SCEP_ALLOW_MULTIPLE_SIGNER_CERT = 0x0002, SCEP_STRICT_SENDER_NONCE = 0x0004, } SCEP_FLAGS; typedef enum { SCEP_PARAM_SENDERNONCE = 0x0001, } SCEP_PARAM; #ifndef OPENSSL_NO_ENGINE struct engine_params_t { char *name; char *value; struct engine_params_t *next; }; #endif /* OPENSSL_NO_ENGINE */ typedef struct { SCEP_VERBOSITY verbosity; const EVP_MD *sigalg; const EVP_CIPHER *encalg; BIO *log; SCEP_FLAGS flags; #ifndef OPENSSL_NO_ENGINE ENGINE *engine; int internal_engine; struct engine_params_t *params; #endif /* OPENSSL_NO_ENGINE */ } SCEP_CONFIGURATION; typedef struct { int messageType; int pkiStatus; int failInfo; int senderNonce; int recipientNonce; int transId; int extensionReq; } SCEP_OIDS; typedef struct { SCEP_CONFIGURATION *configuration; SCEP_OIDS *oids; SCEP_PARAM params_set; unsigned char senderNonce[NONCE_LENGTH]; } SCEP; typedef struct pkcs7_issuer_and_subject_st { X509_NAME *issuer; X509_NAME *subject; } PKCS7_ISSUER_AND_SUBJECT; /* public return value containing all relevant values of a request */ typedef struct { SCEP_PKISTATUS pkiStatus; SCEP_FAILINFO failInfo; char *transactionID; unsigned char senderNonce[NONCE_LENGTH]; unsigned char recipientNonce[NONCE_LENGTH]; ASN1_TYPE *challenge_password; X509 *signer_certificate; char *messageType_str; SCEP_MESSAGE_TYPE messageType; /* Different types of message content for different operations. * Contains the required data for the specified operation * if there is data attached to the request/response */ union { struct { X509_REQ *request; int initialEnrollment; }; /* PKCSReq */ PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; /* GetCert */ PKCS7_ISSUER_AND_SUBJECT *issuer_and_subject; /* GetCertInitial */ struct { SCEP_OPERATION request_type; /* CertRep depends on request type */ union { STACK_OF(X509) *certs; /* all except GetCRL response */ X509_CRL *crl; /* for GetCRL */ PKCS7 *messageData; /* internal */ }; }; }; } SCEP_DATA; /* internal structure to handle operations */ struct p7_data_t { PKCS7 *p7; BIO *bio; PKCS7_SIGNER_INFO *signer_info; unsigned char sender_nonce[NONCE_LENGTH]; char *transaction_id; }; /* External functions */ SCEP_ERROR scep_init(SCEP **handle); void scep_cleanup(SCEP *handle); SCEP_ERROR scep_conf_set(SCEP *handle, SCEPCFG_TYPE type, ...); SCEP_ERROR scep_param_set(SCEP *handle, SCEP_PARAM type, void *value); SCEP_ERROR scep_param_get(SCEP *handle, SCEP_PARAM type, void **value); #ifndef OPENSSL_NO_ENGINE SCEP_ERROR scep_engine_get(SCEP *handle, ENGINE **e); #endif /* OPENSSL_NO_ENGINE */ char *scep_strerror(SCEP_ERROR err); char *scep_fail_info_str(SCEP_FAILINFO fail_info); SCEP_ERROR scep_PKCS7_base64_encode(SCEP *handle, PKCS7 *p7, char **encoded); SCEP_ERROR scep_new_selfsigned_X509( SCEP *handle, X509_REQ *req, EVP_PKEY *req_key, X509 **cert); SCEP_ERROR SCEP_DATA_free(SCEP_DATA *data); SCEP_ERROR scep_certrep( SCEP *handle, char *transactionID, unsigned char *senderNonce, SCEP_PKISTATUS pkiStatus, SCEP_FAILINFO failInfo, X509 *requestedCert, X509 *sig_cert, EVP_PKEY *sig_key, X509 *enc_cert, STACK_OF(X509) *additionalCerts, X509_CRL *crl, PKCS7 **pkiMessage); SCEP_ERROR scep_pkcsreq( SCEP *handle, X509_REQ *req, X509 *sig_cert, EVP_PKEY *sig_key, X509 *enc_cert, PKCS7 **pkiMessage); SCEP_ERROR scep_unwrap( SCEP *handle, PKCS7 *pkiMessage, X509 *ca_cert, X509 *dec_cert, EVP_PKEY *dec_key, SCEP_DATA **output); SCEP_ERROR scep_unwrap_response( SCEP *handle, PKCS7 *pkiMessage, X509 *ca_cert, X509 *request_cert, EVP_PKEY *request_key, SCEP_OPERATION request_type, SCEP_DATA **output); SCEP_ERROR scep_get_cert_initial( SCEP *handle, X509_REQ *req, X509 *sig_cert, EVP_PKEY *sig_key, X509 *cacert, X509 *enc_cert, PKCS7 **pkiMessage); SCEP_ERROR scep_get_cert( SCEP *handle, X509 *sig_cert, EVP_PKEY *sig_key, X509_NAME *issuer, ASN1_INTEGER *serial, X509 *enc_cert, PKCS7 **pkiMessage); SCEP_ERROR scep_get_crl( SCEP *handle, X509 *sig_cert, EVP_PKEY *sig_key, X509 *req_cert, X509 *enc_cert, PKCS7 **pkiMessage); SCEP_ERROR scep_getcacert_reply( SCEP *handle, STACK_OF(X509) *certs, X509 *signcert, EVP_PKEY *key, PKCS7 **p7); /* Internal functions */ /* scep.c */ SCEP_ERROR scep_create_oids(SCEP *); /* configuration.c */ SCEP_ERROR scep_conf_init(SCEP *handle); void scep_conf_free(SCEP_CONFIGURATION *conf); SCEP_ERROR scep_conf_sanity_check(SCEP *handle); /* util.c */ SCEP_ERROR scep_calculate_transaction_id_pubkey( SCEP *handle, EVP_PKEY *pubkey, char **transaction_id); void _scep_log(SCEP *handle, SCEP_VERBOSITY verbosity, const char *file, int line, char *format, ...); SCEP_ERROR scep_calculate_transaction_id_ias_type( SCEP *handle, PKCS7_ISSUER_AND_SERIAL *ias, char *messageType, char **transaction_id); int X509_REQ_cmp(X509_REQ *req1, X509_REQ *req2); DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SUBJECT) /* message.c */ SCEP_ERROR scep_p7_client_init( SCEP *handle, X509 *sig_cert, EVP_PKEY *sig_key, struct p7_data_t *p7data); SCEP_ERROR scep_p7_server_init(SCEP *handle, struct p7_data_t *p7data); SCEP_ERROR scep_p7_final(SCEP *handle, struct p7_data_t *p7data, PKCS7 **p7); SCEP_ERROR scep_pkiMessage( SCEP *handle, char *messageType, BIO *data, X509 *enc_cert, struct p7_data_t *p7data); #endif /* SCEP_H_ */