1/* src/scep.h */ 2 3#ifndef SCEP_H_ 4#define SCEP_H_ 5 6#include <stdarg.h> 7#include <string.h> 8#include <libgen.h> 9 10#include <openssl/x509.h> 11#include <openssl/x509v3.h> 12#include <openssl/evp.h> 13#include <openssl/cms.h> 14#include <openssl/pem.h> 15#include <openssl/rand.h> 16#include <openssl/err.h> 17#ifndef OPENSSL_NO_ENGINE 18#include <openssl/engine.h> 19#endif /* OPENSSL_NO_ENGINE */ 20 21#define DEFAULT_SIGALG EVP_md5() 22#define DEFAULT_ENCALG EVP_des_cbc() 23#define DEFAULT_VERBOSITY ERROR 24 25#define libscep_VERSION_MAJOR @libscep_VERSION_MAJOR@ 26#define libscep_VERSION_MINOR @libscep_VERSION_MINOR@ 27#define libscep_STR(x) #x 28#define libscep_VERSION_STR(major, minor) "scep-client v" libscep_STR(major) "." libscep_STR(minor) 29 30#define SCEP_MSG_PKCSREQ_STR "19" 31#define SCEP_MSG_CERTREP_STR "3" 32#define SCEP_MSG_GETCERTINITIAL_STR "20" 33#define SCEP_MSG_GETCERT_STR "21" 34#define SCEP_MSG_GETCRL_STR "22" 35 36#define SCEP_PKISTATUS_SUCCESS "0" 37#define SCEP_PKISTATUS_FAILURE "2" 38#define SCEP_PKISTATUS_PENDING "3" 39 40 41#define SCEP_BAD_ALG_NR "0" 42#define SCEP_BAD_MESSAGE_CHECK_NR "1" 43#define SCEP_BAD_REQUEST_NR "2" 44#define SCEP_BAD_TIME_NR "3" 45#define SCEP_BAD_CERT_ID_NR "4" 46 47// number of nonce bytes, defined by protocol 48#define NONCE_LENGTH 16 49 50#define SCEP_SELFSIGNED_EXPIRE_DAYS 7 51 52#define SCEP_MIME_GETCA_RA "application/x-x509-ca-ra-cert" 53#define SCEP_MIME_GETCA "application/x-x509-ca-cert" 54 55#define scep_log(handle, verbosity, format, ...) \ 56 _scep_log(handle, verbosity, __FILE__, __LINE__, format, ##__VA_ARGS__) 57 58#define SCEP_ERR(type, msg, ...) \ 59 do { \ 60 error = type; \ 61 if(msg) \ 62 scep_log(handle, FATAL, msg, ##__VA_ARGS__);\ 63 goto finally; \ 64 } while(0) 65 66#define OSSL_ERR(msg, ...) \ 67 do { \ 68 ERR_print_errors(handle->configuration->log); \ 69 SCEP_ERR(SCEPE_OPENSSL, msg, ##__VA_ARGS__); \ 70 } while(0) 71 72typedef enum { 73 FATAL, 74 ERROR, 75 WARN, 76 INFO, 77 DEBUG, 78} SCEP_VERBOSITY; 79 80typedef enum { 81 /* Global options */ 82 SCEPCFG_VERBOSITY, 83 SCEPCFG_SIGALG, 84 SCEPCFG_ENCALG, 85 SCEPCFG_LOG, 86 87#ifndef OPENSSL_NO_ENGINE 88 /* Engine stuff */ 89 SCEPCFG_ENGINE, 90 SCEPCFG_ENGINE_OBJ, 91 SCEPCFG_ENGINE_PARAM, 92#endif /* OPENSSL_NO_ENGINE */ 93 94 /* Flags to be set */ 95 SCEPCFG_FLAG_CLEAR, // clear all flags 96 SCEPCFG_FLAG_SET, 97} SCEPCFG_TYPE; 98 99typedef enum { 100 SCEPE_OK, 101 SCEPE_MEMORY, 102 SCEPE_UNKNOWN_CONFIGURATION, 103 SCEPE_UNKOWN_OPERATION, 104 SCEPE_DUPLICATE_BIO, 105 SCEPE_PROTOCOL, 106 107 SCEPE_INVALID_CONTENT, 108 SCEPE_INVALID_PARAMETER, 109 SCEPE_UNHANDLED, 110 111 SCEPE_PARAM, 112 113 SCEPE_NYI, 114 SCEPE_OPENSSL, 115 116 SCEPE_INTERNAL, 117 118 // this always needs to be the last error for unit tests. It is used to 119 // make sure we test all error messages. 120 SCEPE_DUMMY_LAST_ERROR, 121} SCEP_ERROR; 122 123typedef enum { 124 SCEPOP_NONE, 125 SCEPOP_GETCACERT, 126 SCEPOP_PKCSREQ, 127 SCEPOP_GETCERT, 128 SCEPOP_GETCRL, 129 SCEPOP_GETNEXTCACERT, 130 SCEPOP_GETCERTINITIAL, 131 SCEPOP_CERTREP, 132} SCEP_OPERATION; 133 134typedef enum { 135 SCEP_SUCCESS = 0, 136 SCEP_FAILURE = 2, 137 SCEP_PENDING = 3, 138} SCEP_PKISTATUS; 139 140typedef enum { 141 SCEP_BAD_ALG = 0, 142 SCEP_BAD_MESSAGE_CHECK = 1, 143 SCEP_BAD_REQUEST = 2, 144 SCEP_BAD_TIME = 3, 145 SCEP_BAD_CERT_ID = 4, 146} SCEP_FAILINFO; 147 148typedef enum { 149 SCEP_MSG_PKCSREQ = 19, 150 SCEP_MSG_CERTREP = 3, 151 SCEP_MSG_GETCERTINITIAL = 20, 152 SCEP_MSG_GETCERT = 21, 153 SCEP_MSG_GETCRL = 22, 154} SCEP_MESSAGE_TYPE; 155 156typedef enum { 157 SCEP_SKIP_SIGNER_CERT = 0x0001, 158 SCEP_ALLOW_MULTIPLE_SIGNER_CERT = 0x0002, 159 SCEP_STRICT_SENDER_NONCE = 0x0004, 160} SCEP_FLAGS; 161 162typedef enum { 163 SCEP_PARAM_SENDERNONCE = 0x0001, 164} SCEP_PARAM; 165 166#ifndef OPENSSL_NO_ENGINE 167struct engine_params_t { 168 char *name; 169 char *value; 170 struct engine_params_t *next; 171}; 172#endif /* OPENSSL_NO_ENGINE */ 173 174typedef struct { 175 SCEP_VERBOSITY verbosity; 176 const EVP_MD *sigalg; 177 const EVP_CIPHER *encalg; 178 BIO *log; 179 SCEP_FLAGS flags; 180#ifndef OPENSSL_NO_ENGINE 181 ENGINE *engine; 182 int internal_engine; 183 struct engine_params_t *params; 184#endif /* OPENSSL_NO_ENGINE */ 185} SCEP_CONFIGURATION; 186 187typedef struct { 188 int messageType; 189 int pkiStatus; 190 int failInfo; 191 int senderNonce; 192 int recipientNonce; 193 int transId; 194 int extensionReq; 195} SCEP_OIDS; 196 197typedef struct { 198 SCEP_CONFIGURATION *configuration; 199 SCEP_OIDS *oids; 200 SCEP_PARAM params_set; 201 unsigned char senderNonce[NONCE_LENGTH]; 202} SCEP; 203 204typedef struct pkcs7_issuer_and_subject_st 205{ 206 X509_NAME *issuer; 207 X509_NAME *subject; 208} PKCS7_ISSUER_AND_SUBJECT; 209 210/* public return value containing all relevant values of a request */ 211typedef struct { 212 SCEP_PKISTATUS pkiStatus; 213 SCEP_FAILINFO failInfo; 214 char *transactionID; 215 unsigned char senderNonce[NONCE_LENGTH]; 216 unsigned char recipientNonce[NONCE_LENGTH]; 217 ASN1_TYPE *challenge_password; 218 X509 *signer_certificate; 219 char *messageType_str; 220 SCEP_MESSAGE_TYPE messageType; 221 /* Different types of message content for different operations. 222 * Contains the required data for the specified operation 223 * if there is data attached to the request/response 224 */ 225 union { 226 struct { 227 X509_REQ *request; 228 int initialEnrollment; 229 }; /* PKCSReq */ 230 PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; /* GetCert */ 231 PKCS7_ISSUER_AND_SUBJECT *issuer_and_subject; /* GetCertInitial */ 232 233 struct { 234 SCEP_OPERATION request_type; 235 /* CertRep depends on request type */ 236 union { 237 STACK_OF(X509) *certs; /* all except GetCRL response */ 238 X509_CRL *crl; /* for GetCRL */ 239 240 PKCS7 *messageData; /* internal */ 241 }; 242 }; 243 }; 244} SCEP_DATA; 245 246/* internal structure to handle operations */ 247struct p7_data_t { 248 PKCS7 *p7; 249 BIO *bio; 250 PKCS7_SIGNER_INFO *signer_info; 251 unsigned char sender_nonce[NONCE_LENGTH]; 252 char *transaction_id; 253}; 254 255/* External functions */ 256SCEP_ERROR scep_init(SCEP **handle); 257void scep_cleanup(SCEP *handle); 258SCEP_ERROR scep_conf_set(SCEP *handle, SCEPCFG_TYPE type, ...); 259SCEP_ERROR scep_param_set(SCEP *handle, SCEP_PARAM type, void *value); 260SCEP_ERROR scep_param_get(SCEP *handle, SCEP_PARAM type, void **value); 261#ifndef OPENSSL_NO_ENGINE 262SCEP_ERROR scep_engine_get(SCEP *handle, ENGINE **e); 263#endif /* OPENSSL_NO_ENGINE */ 264char *scep_strerror(SCEP_ERROR err); 265char *scep_fail_info_str(SCEP_FAILINFO fail_info); 266SCEP_ERROR scep_PKCS7_base64_encode(SCEP *handle, PKCS7 *p7, char **encoded); 267SCEP_ERROR scep_new_selfsigned_X509( 268 SCEP *handle, X509_REQ *req, EVP_PKEY *req_key, X509 **cert); 269SCEP_ERROR SCEP_DATA_free(SCEP_DATA *data); 270SCEP_ERROR scep_certrep( 271 SCEP *handle, char *transactionID, unsigned char *senderNonce, 272 SCEP_PKISTATUS pkiStatus, SCEP_FAILINFO failInfo, X509 *requestedCert, 273 X509 *sig_cert, EVP_PKEY *sig_key, X509 *enc_cert, 274 STACK_OF(X509) *additionalCerts, X509_CRL *crl, PKCS7 **pkiMessage); 275SCEP_ERROR scep_pkcsreq( 276 SCEP *handle, X509_REQ *req, X509 *sig_cert, EVP_PKEY *sig_key, 277 X509 *enc_cert, PKCS7 **pkiMessage); 278SCEP_ERROR scep_unwrap( 279 SCEP *handle, PKCS7 *pkiMessage, X509 *ca_cert, X509 *dec_cert, 280 EVP_PKEY *dec_key, SCEP_DATA **output); 281SCEP_ERROR scep_unwrap_response( 282 SCEP *handle, PKCS7 *pkiMessage, X509 *ca_cert, 283 X509 *request_cert, EVP_PKEY *request_key, 284 SCEP_OPERATION request_type, SCEP_DATA **output); 285SCEP_ERROR scep_get_cert_initial( 286 SCEP *handle, X509_REQ *req, X509 *sig_cert, EVP_PKEY *sig_key, 287 X509 *cacert, X509 *enc_cert, 288 PKCS7 **pkiMessage); 289SCEP_ERROR scep_get_cert( 290 SCEP *handle, X509 *sig_cert, EVP_PKEY *sig_key, 291 X509_NAME *issuer, ASN1_INTEGER *serial, X509 *enc_cert, 292 PKCS7 **pkiMessage); 293SCEP_ERROR scep_get_crl( 294 SCEP *handle, X509 *sig_cert, EVP_PKEY *sig_key, 295 X509 *req_cert, X509 *enc_cert, 296 PKCS7 **pkiMessage); 297SCEP_ERROR scep_getcacert_reply( 298 SCEP *handle, STACK_OF(X509) *certs, X509 *signcert, 299 EVP_PKEY *key, PKCS7 **p7); 300 301/* Internal functions */ 302 303/* scep.c */ 304SCEP_ERROR scep_create_oids(SCEP *); 305 306/* configuration.c */ 307SCEP_ERROR scep_conf_init(SCEP *handle); 308void scep_conf_free(SCEP_CONFIGURATION *conf); 309SCEP_ERROR scep_conf_sanity_check(SCEP *handle); 310 311/* util.c */ 312SCEP_ERROR scep_calculate_transaction_id_pubkey( 313 SCEP *handle, EVP_PKEY *pubkey, char **transaction_id); 314void _scep_log(SCEP *handle, SCEP_VERBOSITY verbosity, const char *file, 315 int line, char *format, ...); 316SCEP_ERROR scep_calculate_transaction_id_ias_type( 317 SCEP *handle, PKCS7_ISSUER_AND_SERIAL *ias, char *messageType, char **transaction_id); 318int X509_REQ_cmp(X509_REQ *req1, X509_REQ *req2); 319DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SUBJECT) 320 321/* message.c */ 322SCEP_ERROR scep_p7_client_init( 323 SCEP *handle, X509 *sig_cert, EVP_PKEY *sig_key, 324 struct p7_data_t *p7data); 325SCEP_ERROR scep_p7_server_init(SCEP *handle, struct p7_data_t *p7data); 326SCEP_ERROR scep_p7_final(SCEP *handle, struct p7_data_t *p7data, PKCS7 **p7); 327 328SCEP_ERROR scep_pkiMessage( 329 SCEP *handle, char *messageType, BIO *data, 330 X509 *enc_cert, 331 struct p7_data_t *p7data); 332#endif /* SCEP_H_ */ 333