HTTPS PKCS11 newbie
Hey fellows, I want your help, to implement an integration with SafeNet HSM Hardware. I know OpenSSL, but never used with PKCS#11. I have a HTTPS server and wonders how do I inform the certificate, privatekey and passphrase for the HTTPS handshake using PKCS#11. How to change my functions load_key and load_cert to use PKCS#11 ?? Any Good Sample ?? I Try OPENSC samples, but .. I am posting my code that is based on the application OpenSSL s_client command line: Or How to make s_client use my HSM, connecting in slot, informing PIN, etc ... obs: i am using openssl-0.9.8g Bool Initialize(Bool AInitVars) { EVP_PKEY* key = NULL; X509* cert = NULL; OpenSSL_add_ssl_algorithms(); SSL_load_error_strings(); key = load_key(sslErr, nOptions.KeyFiles[2], nOptions.PassPhrase); // HSM if (!key) { ERR_print_errors(sslErr); bRet = False; goto end; } cert = load_cert(sslErr, nOptions.CertificateFiles[2], nOptions.PassPhrase); // HSM if (!cert) { ERR_print_errors(sslErr); bRet = False; goto end; } sslCtx=SSL_CTX_new(sslMeth); SSL_CTX_set_verify(sslCtx,nServerVerify,verify_callback_https); if (!set_cert_key_stuff(sslCtx,cert,key)) { bRet = False; goto end; } if ((!SSL_CTX_load_verify_locations(sslCtx,nOptions.CertificateFiles[2],NULL)) || (!SSL_CTX_set_default_verify_paths(sslCtx))) { /* BIO_printf(bio_err,error setting default verify locations\n); */ ERR_print_errors(sslErr); /* goto end; */ } ssl = SSL_new(sslCtx); sslBio = BIO_new_socket(this-Handle(),BIO_NOCLOSE); SSL_set_bio(ssl, sslBio, sslBio); } EVP_PKEY* load_key(BIO *err, const char *file /*PEM FILE*/, const char *pass) { BIO *key=NULL; EVP_PKEY *pkey=NULL; PW_CB_DATA cb_data; cb_data.password = pass; cb_data.prompt_info = file; key=BIO_new(BIO_s_file()); if (key == NULL) { ERR_print_errors(err); goto end; } if (file == NULL) { setvbuf(stdin, NULL, _IONBF, 0); BIO_set_fp(key,stdin,BIO_NOCLOSE); } else { if (BIO_read_filename(key,file) = 0) { BIO_printf(err, Error opening client private key file %s\n, file); ERR_print_errors(err); goto end; } // PEM FORMAT - DEFAULT pkey=PEM_read_bio_PrivateKey(key, NULL, (pem_password_cb *)password_callback, cb_data); } end: if (key != NULL) BIO_free(key); if (pkey == NULL) msprintf(unable to load client private key file\n); return(pkey); } X509* load_cert(BIO *err, const char *file, const char *pass) { BUF_MEM *buf=NULL; X509 *x=NULL; BIO *cert=NULL; if ((cert=BIO_new(BIO_s_file())) == NULL){ ERR_print_errors(err); goto end; } if (file == NULL){ setvbuf(stdin, NULL, _IONBF, 0); BIO_set_fp(cert,stdin,BIO_NOCLOSE); } else{ if (BIO_read_filename(cert,file) = 0) { BIO_printf(err, Error opening client certificate file %s\n, file); ERR_print_errors(err); goto end; } } // PEM FORMAT - DEFAULT x=PEM_read_bio_X509_AUX(cert,NULL, (pem_password_cb *)password_callback, NULL); end: if (x == NULL){ BIO_printf(err,unable to load certificate\n); ERR_print_errors(err); } if (cert != NULL) BIO_free(cert); if (buf != NULL) BUF_MEM_free(buf); return(x); } Thanks in Advanced Ricardo.
Re: HTTPS PKCS11 newbie
Hello Patrick, Thanks for help ... - My Background: Working with a server application that has a programming language (ADVPL), in the server I am responsible for some protocols such as http/https - server/client :) and now I am having to use an HSM. Currently supports only the format PEM and the files are saved to disk, with the passphrase in the server INI :( .Ex: [HTTPS] Enable=1 Port=443 Path=c:\webpath Instances=20,200 [SSLConfigure] SSL2=0 SSL3=1 TLS1=1 CertificateClient=c:\certs\xxx.pem KeyClient=C:\certs\xxx.pem PassPhrase= I already use OpenSSL in my application server, now I will have to bear a hardware solution using SafeNet. Yes, i have a ProtectToolkit C SDK (linux32,win32), with examples that explain how to handling: - Slots - PIN - Private Keys and Certificates - Sign and Verify. But I want an example of a requisition https client, using the keys, certificate and password contained in hardware (emulator). How can I use the s_client for this ? it would help very much ... instead this way: openssl s_client -connect host:443 -cert xxx.pem -key xxx.pem -pass xxx -CApath xxx.pem -ssl3 Thanks in Advanced Ricardo ps: Sorry for English On Wed, Sep 17, 2008 at 3:14 PM, Patrick Patterson [EMAIL PROTECTED] wrote: Hi Ricardo: On September 17, 2008 12:52:23 pm Ricardo Garcia Reis wrote: Hey fellows, I want your help, to implement an integration with SafeNet HSM Hardware. I know OpenSSL, but never used with PKCS#11. The Engine interface is your friend :) And WHICH Safenet HSM? Have you taken a look at their SDK? They have several good examples in the OpenSSL Appendix there that probably do what you want. The other thing that you will need are their patches to OpenSSL to make the engine interface able to talk to the HSM, or it will never work. I have a HTTPS server and wonders how do I inform the certificate, privatekey and passphrase for the HTTPS handshake using PKCS#11. How to change my functions load_key and load_cert to use PKCS#11 ?? Any Good Sample ?? I Try OPENSC samples, but .. Did you write this server yourself? If so, then you really should talk to Safenet and get the SDK if you don't already have it, and probably a development support contract. LibCrystoki and OpenSSL are a bit tricky in how they work together :) Other than that, to get the command line tools working, it should be a matter of editing your openssl.cnf file to have something like (if you have a CA3, or equivalent - check your documentation): [ openssl_init ] engines = engine_section oid_section = new_oids [ engine_section ] lunahsm = luna_hsm [ smartcard_section ] engine_id = LunaCA3 init = 0 and your /etc/Chrystoki.conf file to have a section that looks like: EngineLunaCA3 = { LibPath = /usr/lunapcm/lib/libCryptoki2.so; EngineInit=1:10:11; } And then # login to the HSM sautil -o -s 1 -i 10:11 # do something with s_client openssl s_client -connect remoteserver:443 -engine LunaCA3 -key sautil-generated.key -cert \ client-cert.pem # log out of the HSM sautil -c -s 1 -i 10:11 But, as I said, it's probably best to talk to SafeNet directly, since the entire process of getting the right .key file is a bit tricky. Have fun. -- Patrick Patterson President and Chief PKI Architect, Carillon Information Security Inc. http://www.carillon.ca __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
s_client GET request
Hello, I would like to know how to hold a requisition s_client GET https that the server was connected ?? Ex: GET /Nfe/services/NfeStatusServico?wsdl HTTP/1.1\r\nHost: hnfe.sefaz.es.gov.br\r\nConnection: Keep-Alive\r\nAccept: */*\r\n It would have any other apps I can do this test? Thanks!! Ricardo
HTTPS With SSL_ERROR_ZERO_RETURN
Hello All, I can not connect to a HTTPS server of WebServices. ( https://hnfe.sefaz.es.gov.br/Nfe/wsdl/nfeStatusServico.wsdl) The error occurs when the function SSL_read() is calling, returning 0 and SSL_get_error () equals SSL_ERROR_ZERO_RETURN. The problem is not the certificates, because when installing in firefox/IE to view the WSDL in the browser, its ok. Using ethereal, there was 1 extra handshake between this sample and firefox/IE. I created a simple program for example that reproduces the problem. #include stdio.h #include winsock2.h #include ws2tcpip.h #include windows.h #include openssl/x509.h #include openssl/ssl.h #include openssl/err.h #include openssl/pem.h #include openssl/rand.h #define DEFAULT_FAMILY AF_INET #define DEFAULT_SOCKTYPESOCK_STREAM #define DEFAULT_PORT443 static unsigned char dh512_p[]={ 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, 0x47,0x74,0xE8,0x33, }; static unsigned char dh512_g[]={ 0x02, }; SOCKET sock = INVALID_SOCKET; int chkSSL(int AError, SSL *s, BIO *bio_e); DH *GetDH512(void); int myReceiveLine( SSL *ssl, char *data, int maxDataLen, int timeOut); bool WaitForReceive(long secs,long uSecs); //-- int main(int argc, char **argv) { ADDRINFO Hints, *AddrInfo = NULL, *AI; WSADATA wsaData; int nFamily = DEFAULT_FAMILY; int nSockType = DEFAULT_SOCKTYPE; char szRemoteAddrString[128]; char szRemoteName[64]; char *szPort = DEFAULT_PORT; char scommand[512]; // VARIAVEIS SSL int nServerVerify; int nServerSessionIdContext; char szCertificate[256]; SSL *ssl=NULL; SSL_CTX *ctx=NULL; SSL_METHOD *meth=NULL; BIO *sslBio; BIO *sslErr; if(argc 5){ printf(Usage:\n sample HOST PORT CERTPEMPATH PASSPHRASE); return(0); } if(WSAStartup(MAKEWORD(2,2), wsaData)){ printf(ERROR: WSAStartup failed); goto Cleanup; } strncpy(szRemoteName, argv[1], sizeof(szRemoteName)); szRemoteName[63] = '\0'; printf(Communicating with server - %hs\r\n, szRemoteName); printf(Communicating with port - %hs\r\n, szPort); memset(Hints, 0, sizeof(Hints)); Hints.ai_family = nFamily; Hints.ai_socktype = nSockType; if(getaddrinfo(szRemoteName, szPort, Hints, AddrInfo) != 0){ printf(ERROR: Couldn't get resolve the server name/address!); goto Cleanup; } AI = AddrInfo; if (AI == NULL) { printf(ERROR: Unable to connect to any of the server's addresses!); goto Cleanup; } if(AI-ai_family == DEFAULT_FAMILY) { sock = socket(AI-ai_family, AI-ai_socktype, AI-ai_protocol); if (sock != INVALID_SOCKET){ if(connect(sock, AI-ai_addr, AI-ai_addrlen) == SOCKET_ERROR) { // Connect failed, let's close this socket and try again on the next address in the list printf(FAIL: Failed to connect); closesocket(sock); } } if (getnameinfo(AI-ai_addr, AI-ai_addrlen, szRemoteAddrString, sizeof(szRemoteAddrString), NULL, 0, NI_NUMERICHOST) != 0) strcpy(szRemoteAddrString, ); printf(Succeeded Conected with the server: %hs, szRemoteAddrString); } else printf(INVALID: Failed to connect with %hs, AI-ai_addr-sa_data); nServerVerify = SSL_VERIFY_NONE; nServerSessionIdContext = 1; //---START INITIALIZE HANDSHAKE-- SSL_load_error_strings(); SSL_library_init(); sslErr = BIO_new_file(ssl.log,a); meth=SSLv3_client_method(); ctx = SSL_CTX_new(meth); SSL_CTX_set_quiet_shutdown(ctx,1); int nOffProtocol = 0; nOffProtocol |= SSL_OP_NO_SSLv2; nOffProtocol |= SSL_OP_NO_TLSv1; SSL_CTX_set_options(ctx, nOffProtocol); SSL_CTX_sess_set_cache_size(ctx, 2); SSL_CTX_set_session_id_context(ctx, (const unsigned char*)nServerSessionIdContext, sizeof(nServerSessionIdContext)); strncpy(szCertificate, argv[3], sizeof(szCertificate)); szRemoteName[255] = '\0'; if( SSL_CTX_use_certificate_file(ctx, szCertificate, SSL_FILETYPE_PEM) = 0){ printf( ERROR: unable to get certificate from '%s'\n, argv[3]); ERR_print_errors(sslErr); goto Cleanup; } SSL_CTX_set_default_passwd_cb_userdata(ctx, argv[4]); if (SSL_CTX_use_PrivateKey_file(ctx, szCertificate, SSL_FILETYPE_PEM) = 0){ printf(ERROR: unable to get private key from '%s'\n,argv[3]); ERR_print_errors(sslErr);
Intermediate CA
Hi everybody, I've been get some problems with WebService Client on HTTPS. I have 1 certificate and 2 intermediate CA´s to access this server. Testing my Browser, if i remove any one of the intemediate CA's, i get this: HTTP Error 403.7 - Forbidden: SSL client certificate is required. I Have the same error in my application. I've been tried include the Intermediate CA's using many ways, but without successful. Bool tSSLSocketAPI::SetCertificateFiles(mspchar ACertFile, mspchar AKeyFile) { if (ACertFile!= NULL) { // INTERMEDIATE CA DONT HAVE KEY if (AKeyFile == NULL) { FILE *fp; X509 *cert; if (!(fp = fopen(ACertFile, r))) { msprintf( OPS1unable to open certificate ); return false; } cert = PEM_read_X509(fp, NULL, NULL, NULL); if (cert==NULL){ msprintf( OPS2unable to read certificate ); return false; } fclose (fp); if (SSL_CTX_add_client_CA(sslCtx, cert) 1 ) return false; return true; } if( chkSSL( SSL_CTX_use_certificate_file(sslCtx, ACertFile, SSL_FILETYPE_PEM), ssl, sslErr ) = 0) { msprintf( unable to get certificate from '%s'\n, ACertFile); ERR_print_errors(sslErr); return false; } if (nOptions.PassPhrase) SSL_CTX_set_default_passwd_cb_userdata(sslCtx, nOptions.PassPhrase ); if (SSL_CTX_use_PrivateKey_file(sslCtx, AKeyFile, SSL_FILETYPE_PEM) = 0) { msprintf(unable to get private key from '%s'\n,AKeyFile); ERR_print_errors(sslErr); return false; } if (!SSL_CTX_check_private_key(sslCtx)) { msprintf( Private key does not match the certificate public key\n); return false; } if (nOptions.PassPhrase) SSL_CTX_set_default_passwd_cb_userdata(sslCtx, NULL); } return true; } . . I've been tried this functions : SSL_CTX_add_client_CA(...) SSL_CTX_add_extra_chain_cert(...) SSL_CTX_load_verify_locations(...) how add intermediate CA's using openssl ?? Thanks in Advanced. Ricardo G. Reis