------=_Part_7711_19027520.1200679506271
Content-Type: text/plain; charset=WINDOWS-1252
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hello,



As a new user of openssl, I am trying to figure out the certificate
verification process. For this purpose, I created a self-signed "root" CA,
put it in a "trusted" directory and used it to sign a user certificate.



I then used the following command to test the validity of the user
certificate and obtained the response below. Everything seems OK till this
point.

>openssl verify -verbose -CApath trusted -purpose any alicecert.pem


alicecert.pem: OK



Now I would like to write a C program doing the same. For this, I used Vieg=
a
and Messier's Secure Programming Cookbook, recipe 10.5 (BTW, I am not sure
the workaround they propose there is still necessary with latest versions o=
f
openssl =96 any hint welcome).



The problem is that, when verifying the same certificate as before, I now
get a "certificate signature failure" error message, and cannot figure out
what the problem is.



I append my code below (OK, I hate posting long code for review, because I
understand it represents significant work for the reader, but most of it is
simply borrowed from the cookbook, my (apparently bad) contribution is in
the main() function.



Any help would be greatly appreciated. Of course, feel free to ask any
additional information I should provide (like the certificates themselves,
for example).



And apologies for this newbie question: I am afraid the lack of
documentation makes the newcomer's life a bit tricky.



---------------------------------------------------------------------------=
-----



#include

#include

#include

#include

#include

#include

#include



#define PATH "certificates\\"



typedef int (*spc_x509verifycallback_t)(int,X509_STORE_CTX *);



typedef struct {

char *cafile;

char *capath;

char *crlfile;

spc_x509verifycallback_t callback;

STACK_OF(X509) *certs;

STACK_OF(X509_CRL) *crls;

char *use_certfile;

STACK_OF(X509) *use_certs;

char *use_keyfile;

EVP_PKEY *use_key;

int flags;

} spc_x509store_t;



void spc_init_x509store(spc_x509store_t *spc_store)

{

spc_store->cafile=3D0;

spc_store->capath=3D0;

spc_store->crlfile=3D0;

spc_store->callback=3D0;

spc_store->certs=3Dsk_X509_new_null();

spc_store->crls=3Dsk_X509_CRL_new_null();

spc_store->use_certfile=3D0;

spc_store->use_certs=3Dsk_X509_new_null();

spc_store->use_keyfile=3D0;

spc_store->use_key=3D0;

spc_store->flags=3D0;

}



void spc_cleanup_x509store(spc_x509store_t *spc_store)

{

if (spc_store->cafile) free(spc_store->cafile);

if (spc_store->capath) free(spc_store->capath);

if (spc_store->crlfile) free(spc_store->crlfile);

if (spc_store->use_certfile) free(spc_store->use_certfile);

if (spc_store->use_keyfile) free(spc_store->use_keyfile);

if (spc_store->use_key) free (spc_store->use_key);

sk_X509_free(spc_store->certs);

sk_X509_free(spc_store->crls);

sk_X509_free(spc_store->use_certs);

}



void spc_x509store_setcafile(spc_x509store_t *spc_store, char *cafile)

{

if (spc_store->cafile) free(spc_store->cafile);

spc_store->cafile=3D(cafile ? strdup(cafile) : 0);

}



void spc_x509store_setcapath(spc_x509store_t *spc_store, char *capath)

{

if (spc_store->capath) free(spc_store->capath);

spc_store->capath=3D(capath ? strdup(capath) : 0);

}



void spc_x509store_setcrlfile(spc_x509store_t *spc_store, char *crlfile)

{

if (spc_store->crlfile) free(spc_store->crlfile);

spc_store->crlfile=3D(crlfile ? strdup(crlfile) : 0);

}



void spc_x509store_addcert(spc_x509store_t *spc_store,X509 *cert)

{

sk_X509_push(spc_store->certs,cert);

}



void spc_x509store_addcrl(spc_x509store_t *spc_store,X509_CRL *crl)

{

sk_X509_CRL_push(spc_store->crls,crl);

}



void spc_x509store_setcallback(spc_x509store_t
*spc_store,spc_x509verifycallback_t callback)

{

spc_store->callback=3Dcallback;

}



#define SPC_X509STORE_NO_DEFAULT_CAFILE 0X01

#define SPC_X509STORE_NO_DEFAULT_CAPATH 0X02



void spc_x509store_setflags(spc_x509store_t *spc_store,int flags)

{

spc_store->flags|=3Dflags;

}



void spc_x509store_clearflags(spc_x509store_t *spc_store,int flags)

{

spc_store->flags&=3D~flags;

}



int spc_verify_callback(int ok, X509_STORE_CTX *store)

{

if (!ok)

{

fprintf(stderr,"Error:
%s\n",X509_verify_cert_error_string(store->error));

printf("Error:
%s\n",X509_verify_cert_error_string(store->error));

}

return ok;

}



X509_STORE *spc_create_x509store(spc_x509store_t *spc_store)

{

int i;

X509_STORE *store;

X509_LOOKUP *lookup;



store=3DX509_STORE_new();

if (spc_store->callback)

X509_STORE_set_verify_cb_func(store,spc_store->callback);

else

X509_STORE_set_verify_cb_func(store,spc_verify_cal lback);



if (!(lookup=3DX509_STORE_add_lookup(store,X509_LOOKU P_file())))

goto error_exit;

if (!spc_store->cafile)

{

if (!(spc_store->flags & SPC_X509STORE_NO_DEFAULT_CAFILE))

X509_LOOKUP_load_file(lookup,0,X509_FILETYPE_DEFAU LT);

}

else if(!X509_LOOKUP_load_file(lookup,spc_store->cafile,X509_FILETYPE=
_PEM))

goto error_exit;



if (spc_store->crlfile)

{

if(!X509_load_crl_file(lookup,spc_store->crlfile,X509_FILETYPE_=
PEM))

goto error_exit;

X509_STORE_set_flags(store,X509_V_FLAG_CRL_CHECK |
X509_V_FLAG_CRL_CHECK_ALL);

}



if (!(lookup=3DX509_STORE_add_lookup(store,X509_LOOKU P_hash_dir())))

goto error_exit;

if (!spc_store->capath)

{

if (!(spc_store->flags & SPC_X509STORE_NO_DEFAULT_CAPATH))

X509_LOOKUP_add_dir(lookup,0,X509_FILETYPE_DEFAULT );

}

else if(!X509_LOOKUP_add_dir(lookup,spc_store->capath,X509_FILETYPE_P=
EM))

goto error_exit;



for (i=3D0;icerts);i++)

if(!X509_STORE_add_cert(store,sk_X509_value(spc_st ore->certs,i)=
))

goto error_exit;

for (i=3D0;icrls);i++)

if(!X509_STORE_add_crl(store,sk_X509_CRL_value(spc _store->crls,=
i)))

goto error_exit;



return store;



error_exit:

if (store) X509_STORE_free(store);

return 0;

}



int spc_verify_cert(X509 *cert, spc_x509store_t *spc_store)

{

int result=3D-1;

X509_STORE *store=3D0;

X509_STORE_CTX *ctx=3D0;



if (!(store=3Dspc_create_x509store(spc_store))) return -1;

if ((ctx=3DX509_STORE_CTX_new())!=3D0)

{

if (X509_STORE_CTX_init(ctx,store,cert,0)=3D=3D1)

result=3D(X509_verify_cert(ctx)=3D=3D1);

X509_STORE_CTX_free(ctx);

}

X509_STORE_free(store);

return result;

}



int _tmain(int argc, _TCHAR* argv[])

{

FILE* fd;

X509* cert=3DNULL;

X509_NAME *name=3DNULL;

char buf [5000],filename[5000],capath[5000];

spc_x509store_t spc_store;

int res;



strcpy(filename,PATH);

strcat(filename,"alicecert.pem");

fd=3Dfopen(filename,"r");

if (!fd) {printf("Error\n");return -1;}

cert=3DPEM_read_X509(fd,NULL,0,NULL);

if (cert =3D=3D NULL) {ERR_print_errors_fp (stderr);return -1;}

fclose (fd);



spc_init_x509store(&spc_store);

strcpy(capath,PATH);

strcat(capath,"trusted");

spc_x509store_setcapath(&spc_store,capath);

spc_x509store_setflags(&spc_store,SPC_X509STORE_NO_DEFAULT_CAFILE);

spc_x509store_setcallback(&spc_store,spc_verify_callback);



res=3Dspc_verify_cert(cert,&spc_store);



spc_cleanup_x509store(&spc_store);



return 0;

}

------=_Part_7711_19027520.1200679506271
Content-Type: text/html; charset=WINDOWS-1252
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

w Roman">Hello,


w Roman"> 


w Roman">As a new user of openssl, I am trying to figure out the certificat=
e verification process. For this purpose, I created a self-signed "root" CA=
, put it in a "trusted" directory and used it to sign a user certificate.


w Roman"> 


w Roman">I then used the following command to test the validity of the user=
certificate and obtained the response below. Everything seems OK till this=
point.


nt face=3D"Times New Roman">>openssl verify -verbose -CApath trusted -pu=
rpose any alicecert.pem


nt face=3D"Times New Roman">alicecert.pem: OK


w Roman"> 


w Roman">Now I would like to write a C program doing the same. For this, I =
used Viega and Messier's Secure Programming Cookbook, recipe 10.5 (BTW, I a=
m not sure the workaround they propose there is still necessary with latest=
versions of openssl =96 any hint welcome).=20


w Roman"> 


w Roman">The problem is that, when verifying the same certificate as before=
, I now get a "certificate signature failure" error message, and cannot fig=
ure out what the problem is.


w Roman"> 


w Roman">I append my code below (OK, I hate posting long code for review, b=
ecause I understand it represents significant work for the reader, but most=
of it is simply borrowed from the cookbook, my (apparently bad) contributi=
on is in the main() function.


w Roman"> 


w Roman">Any help would be greatly appreciated. Of course, feel free to ask=
any additional information I should provide (like the certificates themsel=
ves, for example).


w Roman"> 


w Roman">And apologies for this newbie question: I am afraid the lack of do=
cumentation makes the newcomer's life a bit tricky.


w Roman"> 


w Roman">------------------------------------------------------------------=
--------------


w Roman"> 


w Roman">  ILY: 'Courier New'">#include FONT-FAMILY: 'Courier New'">
<stdio.h>


none"> er New'">#include 39;Courier New'">
<stdlib.h>


none"> er New'">#include 39;Courier New'">
<string.h>


none"> er New'">#include 39;Courier New'">
<openssl/evp.h>


none"> er New'">#include 39;Courier New'">
<openssl/x509.h>


none"> er New'">#include 39;Courier New'">
<openssl/pem.h>


none"> er New'">#include 39;Courier New'">
<openssl/err.h>


none">=
 


none"> er New'">#define 9;Courier New'">
PATH "certificates\\"


none">=
 


none"> er New'">typedef 9;Courier New'">
int (*spc_x509verifycallback_t)( tyle=3D"COLOR: blue">int,X509_STORE_CTX *);


none">=
 


none"> er New'">typedef 9;Courier New'">
struct {


none">=
      n style=3D"COLOR: blue">char

       =
            &nb=
sp;            n>*cafile;


none">=
      n style=3D"COLOR: blue">char

       =
            &nb=
sp;            n>*capath;


none">=
      n style=3D"COLOR: blue">char

       =
            &nb=
sp;            n>*crlfile;


none">=
      spc_=
x509verifycallback_t
     
callback;


none">=
      STAC=
K_OF(X509)
            &nb=
sp;        
*certs;
p>

none">=
      STAC=
K_OF(X509_CRL)
            &nb=
sp;    
*crls;


none">=
      n style=3D"COLOR: blue">char

       =
            &nb=
sp;            n>*use_certfile;


none">=
      STAC=
K_OF(X509)
            &nb=
sp;        
*use_certs; n>


none">=
      n style=3D"COLOR: blue">char

       =
            &nb=
sp;            n>*use_keyfile;


none">=
      EVP_=
PKEY
            &nb=
sp;            =
  
*use_key;


none">=
      n style=3D"COLOR: blue">int

       =
            &nb=
sp;            =
      
flags;


none">=
} spc_x509store_t;


none">=
 


none"> er New'">void ourier New'">
spc_init_x509store(spc_x509store_t &=
nbsp;
*spc_store)


none">=
{


none">=
      spc_=
store->cafile=3D0;



none">=
      spc_=
store->capath=3D0;



none">=
      spc_=
store->crlfile=3D0;



none">=
      spc_=
store->callback=3D0;


none">=
      spc_=
store->certs=3Dsk_X509_new_null();
      an>


none">=
      spc_=
store->crls=3Dsk_X509_CRL_new_null();


none">=
      spc_=
store->use_certfile=3D0;


none">=
      spc_=
store->use_certs=3Dsk_X509_new_null();


none">=
      spc_=
store->use_keyfile=3D0;


none">=
      spc_=
store->use_key=3D0;



none">=
      spc_=
store->flags=3D0;



none">=
}


none">=
 


none"> er New'">void ourier New'">
spc_cleanup_x509store(spc_x509store_t *spc_store)


none">=
{


none">=
      n style=3D"COLOR: blue">if

(spc_store->cafile) free(spc_store->cafile);


none">=
      n style=3D"COLOR: blue">if

(spc_store->capath) free(spc_store->capath);


none">=
      n style=3D"COLOR: blue">if

(spc_store->crlfile) free(spc_store->crlfile);


none">=
      n style=3D"COLOR: blue">if

(spc_store->use_certfile) free(spc_store->use_certfile);


none">=
      n style=3D"COLOR: blue">if

(spc_store->use_keyfile) free(spc_store->use_keyfile);


none">=
      n style=3D"COLOR: blue">if

(spc_store->use_key) free (spc_store->use_key);


none">=
      sk_X=
509_free(spc_store->certs);


none">=
      sk_X=
509_free(spc_store->crls);


none">=
      sk_X=
509_free(spc_store->use_certs);


none">=
}


none">=
 


none"> er New'">void ourier New'">
spc_x509store_setcafile(spc_x509store_t *spc_store, blue">char *cafile)


none">=
{


none">=
      n style=3D"COLOR: blue">if

(spc_store->cafile) free(spc_store->cafile);


none">=
      spc_=
store->cafile=3D(cafile ? strdup(cafile) : 0);


none">=
}


none">=
 


none"> er New'">void ourier New'">
spc_x509store_setcapath(spc_x509store_t *spc_store, blue">char *capath)


none">=
{


none">=
      n style=3D"COLOR: blue">if

(spc_store->capath) free(spc_store->capath);


none">=
      spc_=
store->capath=3D(capath ? strdup(capath) : 0);


none">=
}


none">=
 


none"> er New'">void ourier New'">
spc_x509store_setcrlfile(spc_x509store_t *spc_store, blue">char *crlfile)


none">=
{


none">=
      n style=3D"COLOR: blue">if

(spc_store->crlfile) free(spc_store->crlfile);


none">=
      spc_=
store->crlfile=3D(crlfile ? strdup(crlfile) : 0);


none">=
}


none">=
 


none"> er New'">void ourier New'">
spc_x509store_addcert(spc_x509store_t *spc_store,X509 *cert)


none">=
{


none">=
      sk_X=
509_push(spc_store->certs,cert);


none">=
}


none">=
 


none"> er New'">void ourier New'">
spc_x509store_addcrl(spc_x509store_t *spc_store,X509_CRL *crl)


none">=
{


none">=
      sk_X=
509_CRL_push(spc_store->crls,crl);


none">=
}


none">=
 


none"> er New'">void ourier New'">
spc_x509store_setcallback(spc_x509store_t *spc_store,spc_x509verifycallbac=
k_t callback)


none">=
{


none">=
      spc_=
store->callback=3Dcallback;


none">=
}


none">=
 


none"> er New'">#define 9;Courier New'">
SPC_X509STORE_NO_DEFAULT_CAFILE 0X01


none"> er New'">#define 9;Courier New'">
SPC_X509STORE_NO_DEFAULT_CAPATH 0X02


none">=
 


none"> er New'">void ourier New'">
spc_x509store_setflags(spc_x509store_t *spc_store, ue">int flags)


none">=
{


none">=
      spc_=
store->flags|=3Dflags;


none">=
}


none">=
 


none"> er New'">void ourier New'">
spc_x509store_clearflags(spc_x509store_t *spc_store, blue">int flags)


none">=
{


none">=
      spc_=
store->flags&=3D~flags;


none">=
}


none">=
 


none"> er New'">int urier New'">
spc_verify_callback(int ok, X509_STORE_=
CTX *store)


none">=
{


none">=
      n style=3D"COLOR: blue">if

(!ok)


none">=
      { pan>


none">=
       =
    
fprintf(stderr,"Error: %s\n",X509=
_verify_cert_error_string(store->error));


none">=
       =
    
printf("Error: %s\n",X509_verify_=
cert_error_string(store->error));


none">=
      } pan>


none">=
      n style=3D"COLOR: blue">return
ok;


none">=
}


none">=
 


none">=
X509_STORE *spc_create_x509store(spc_x509store_t *spc_store)


none">=
{


none">=
      n style=3D"COLOR: blue">int

i;


none">=
      X509=
_STORE *store;


none">=
      X509=
_LOOKUP *lookup;


none">=
 


none">=
      stor=
e=3DX509_STORE_new();



none">=
      n style=3D"COLOR: blue">if

(spc_store->callback)


none">=
       =
    
X509_STORE_set_verify_cb_func(store,spc_sto=
re->callback);


none">=
      n style=3D"COLOR: blue">else


none">=
       =
    
X509_STORE_set_verify_cb_func(store,spc_ver=
ify_callback);


none">=
 


none">=
      n style=3D"COLOR: blue">if

(!(lookup=3DX509_STORE_add_lookup(store,X509_LOOKU P_file())))


none">=
       =
    

goto
error_exit;


none">=
      n style=3D"COLOR: blue">if

(!spc_store->cafile)


none">=
      { pan>


none">=
       =
    

if
(!(spc_store->flags & SPC_X509STORE_NO_DEFAULT_CAFILE)) pan>


none">=
       =
          
X509_LO=
OKUP_load_file(lookup,0,X509_FILETYPE_DEFAULT);


none">=
      } pan>


none">=
      n style=3D"COLOR: blue">else

if (!X509_LOOKUP_load_file(lookup,spc_s=
tore->cafile,X509_FILETYPE_PEM))


none">=
       =
    

goto
error_exit;


none">=
 


none">=
      n style=3D"COLOR: blue">if

(spc_store->crlfile)


none">=
      { pan>


none">=
       =
    

if
(!X509_load_crl_file(lookup,spc_store->crlfile,X509_FILETYPE_P=
EM))


none">=
       =
          
tyle=3D"COLOR: blue">
goto
error_exit;


none">=
       =
    
X509_STORE_set_flags(store,X509_V_FLAG_CRL_=
CHECK | X509_V_FLAG_CRL_CHECK_ALL);


none">=
      } pan>


none">=
 


none">=
      n style=3D"COLOR: blue">if

(!(lookup=3DX509_STORE_add_lookup(store,X509_LOOKU P_hash_dir()))) p>

none">=
       =
    

goto
error_exit;


none">=
      n style=3D"COLOR: blue">if

(!spc_store->capath)


none">=
      { pan>


none">=
       =
    

if
(!(spc_store->flags & SPC_X509STORE_NO_DEFAULT_CAPATH)) pan>


none">=
       =
          
X509_LO=
OKUP_add_dir(lookup,0,X509_FILETYPE_DEFAULT);


none">=
      } pan>


none">=
      n style=3D"COLOR: blue">else

if (!X509_LOOKUP_add_dir(lookup,spc_sto=
re->capath,X509_FILETYPE_PEM))


none">=
       =
    

goto
error_exit;


none">=
 


none">=
      n style=3D"COLOR: blue">for

(i=3D0;i<sk_X509_num(spc_store->certs);i++)


none">=
       =
    

if
(!X509_STORE_add_cert(store,sk_X509_value(spc_stor e->certs,i))=
)


none">=
       =
          
tyle=3D"COLOR: blue">
goto
error_exit;


none">=
      n style=3D"COLOR: blue">for

(i=3D0;i<sk_X509_CRL_num(spc_store->crls);i++)


none">=
       =
    

if
(!X509_STORE_add_crl(store,sk_X509_CRL_value(spc_s tore->crls,i=
)))


none">=
       =
          
tyle=3D"COLOR: blue">
goto
error_exit;


none">=
 


none">=
      n style=3D"COLOR: blue">return
store;


none">=
 


none">=
error_exit:


none">=
      n style=3D"COLOR: blue">if

(store) X509_STORE_free(store);


none">=
      n style=3D"COLOR: blue">return
0;


none">=
}


none">=
 


none"> er New'">int urier New'">
spc_verify_cert(X509 *cert, spc_x509store_t *spc_store)


none">=
{


none">=
      n style=3D"COLOR: blue">int

result=3D-1;


none">=
      X509=
_STORE
 
*store=3D0;


none">=
      X509=
_STORE_CTX *ctx=3D0;



none">=
 


none">=
      n style=3D"COLOR: blue">if

(!(store=3Dspc_create_x509store(spc_store))) r=
eturn
-1;


none">=
      n style=3D"COLOR: blue">if

((ctx=3DX509_STORE_CTX_new())!=3D0)


none">=
      { pan>


none">=
       =
    

if
(X509_STORE_CTX_init(ctx,store,cert,0)=3D=3D1)


none">=
       =
          
result=
=3D(X509_verify_cert(ctx)=3D=3D1);


none">=
       =
    
X509_STORE_CTX_free(ctx);


none">=
      } pan>


none">=
      X509=
_STORE_free(store);



none">=
      n style=3D"COLOR: blue">return
result;


none">=
}


none">=
 


none"> er New'">int urier New'">
_tmain(int argc, _TCHAR* argv[])
=


none">=
{


none">=
      FILE=
* fd;


none">=
      X509=
* cert=3DNULL;


none">=
      X509=
_NAME *name=3DNULL;



none">=
      n style=3D"COLOR: blue">char

buf [5000],filename[5000],capath[5000];


none">=
      spc_=
x509store_t spc_store;


none">=
      n style=3D"COLOR: blue">int

res;


none">=
 


none">=
      strc=
py(filename,PATH);



none">=
      strc=
at(filename,"alicecert.pem
");


none">=
      fd=
=3Dfopen(filename,"r");


none">=
      n style=3D"COLOR: blue">if

(!fd) {printf("Error\n");return n> -1;}


none">=
      cert=
=3DPEM_read_X509(fd,NULL,0,NULL);


none">=
      n style=3D"COLOR: blue">if

(cert =3D=3D NULL) {ERR_print_errors_fp (stderr); e">return -1;}


none">=
  : 1">    =20
fclose (fd);


none"> ier New'"> 


none">=
      spc_=
init_x509store(&spc_store);


none">=
      strc=
py(capath,PATH);


none">=
      strc=
at(capath,"trusted");


none">=
      spc_=
x509store_setcapath(&spc_store,capath);


none">=
      spc_=
x509store_setflags(&spc_store,SPC_X509STORE_NO_DEF AULT_CAFILE);=20


none">=
      spc_=
x509store_setcallback(&spc_store,spc_verify_callba ck);


none">=
 


none">=
      res=
=3Dspc_verify_cert(cert,&spc_store);


none">=
 


none">=
      spc_=
cleanup_x509store(&spc_store);


none">=
 


none">=
      n style=3D"COLOR: blue">return
0;


none">=
}


none">=
 


w Roman"> 



------=_Part_7711_19027520.1200679506271--
__________________________________________________ ____________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majordomo@openssl.org