HTTPS PKCS11 newbie

2008-09-17 Thread Ricardo Garcia Reis
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

2008-09-17 Thread Ricardo Garcia Reis
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

2008-04-28 Thread Ricardo Garcia Reis
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

2008-04-22 Thread Ricardo Garcia Reis
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

2007-09-28 Thread Ricardo Garcia Reis
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