X-Accept-Language: es, en
MIME-Version: 1.0
To: [EMAIL PROTECTED]
Subject: patch to 'apps/ca.c'
Content-Type: multipart/mixed;
boundary="------------52F961108DCCE3CFC0375F40"
This is a multi-part message in MIME format.
--------------52F961108DCCE3CFC0375F40
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
hi,
I have write a small patch to the 'ca.c' program (openssl-0.9.4) to
give it more flexibility on REQ processing.
The idea comes from the comparison between user certificate generation
for Netscape users and for MS IE users.
With Netscape, the client presents the SPKAC containing only the public
key, so the CA can build a spkac file containing the DN DECIDED BY THE
CA.
For example, to generate email-only user certs, some CA (like Verisign)
uses only the CN from the user, and with openssl can process a file
like:
organizationName=Solo direccion de e-mail - Persona no comprobada
organizationalUnitName=Only e-mail address - Subscriber not validated
commonName="The name that the user wants"
SPKAC="the spkac structure"
With MS IE, the CA receives the pkcs10 structure, and the only thing it
can do, using openssl (the req command), is to verify the structure of
the DN, that must be correctly presented as CA expects, and then use the
'ca' program to generate the certificate, or reject it.
Also, for latin people as I am, lots of problems appear with the MS
pkcs10 builder when our tilded vocal chars are used in the DN.
With the patch presented here, the CA can also decide the contents of
the DN for MS IE users, as Verisign actually does, and the problem with
latin chars disappears.
The patch I present here simply adds a new posibility to the -spkac
option, that now admits the use (inside the file) of the SPKAC entry
like before, and a new REQ entry.
The patch also performs minor error detection improvement.
The contenet of the REQ object must be a valid pkcs10 structure in DER
format, base64 encoded in one single line. The 'ca' program then
extracts the public key, verifies the signature and discards the rest of
data, using those from the input file.
For example, if the presented REQ:
-----BEGIN CERTIFICATE REQUEST-----
MIIBDzCBygIBADB1MQswCQYDVQQGEwJFUzELMAkGA1UECBMCQ1MxCzAJBgNVBAcT
AkNTMQ0wCwYDVQQKEwROaXN1MQ0wCwYDVQQLEwROaXN1MRIwEAYDVQQDEwlNLiBN
b2xsYXIxGjAYBgkqhkiG9w0BCQEWC21tQG5pc3Uub3JnMEwwDQYJKoZIhvcNAQEB
BQADOwAwOAIxAMvi+MLsWO9sgGlY45fCPL1anJQqNMuKrlXR6yZo6DXEwsYW5Nfd
/kUSrBDcOXZBSQIDAQABoAAwDQYJKoZIhvcNAQEEBQADMQBZvfFSpxrQeKtzSqHd
fw5v/I7VeVUv7mVu8uk9jQdiW962xZ6LZ6ktxxVUbD6EuMU=
-----END CERTIFICATE REQUEST-----
contains the DN:
C=ES, ST=CS, L=CS, O=Nisu, OU=Nisu, CN=M. [EMAIL PROTECTED]
and the spkac_file is constructed by the CA as:
C = ES
O = None company, none address
OU = Nothing nothing
CN = M. Mollar - untrusted
L = None
ST = None
Email = [EMAIL PROTECTED]
REQ = "the previous req in one line"
the final certificate will have the DN desired by the CA:
C=ES, ST=None, L=None, O=None company, none address, OU=Nothing nothing,
CN=M. Mollar - [EMAIL PROTECTED]
I hope that some one find the patch useful.
Sorry, my english is very bad.
--------------52F961108DCCE3CFC0375F40
Content-Type: text/plain; charset=us-ascii;
name="ca.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="ca.patch"
--- ca.c Fri Aug 6 23:47:09 1999
+++ ca.c.new Mon Aug 16 17:25:06 1999
@@ -157,7 +157,7 @@
" -out file - Where to put the output file(s)\n",
" -outdir dir - Where to put output certificates\n",
" -infiles .... - The last argument, requests to process\n",
-" -spkac file - File contains DN and signed public key and challenge\n",
+" -spkac file - File contains DN and public key as SPKAC or REQ\n",
" -ss_cert file - File contains a self signed cert to sign\n",
" -preserveDN - Don't re-order the DN\n",
" -batch - Don't ask questions\n",
@@ -1926,16 +1926,17 @@
{
STACK_OF(CONF_VALUE) *sk=NULL;
LHASH *parms=NULL;
- X509_REQ *req=NULL;
+ X509_REQ *req=NULL, *ireq=NULL;
CONF_VALUE *cv=NULL;
NETSCAPE_SPKI *spki = NULL;
- unsigned char *spki_der = NULL,*p;
+ unsigned char *data_der = NULL,*p;
X509_REQ_INFO *ri;
char *type,*buf;
EVP_PKEY *pktmp=NULL;
X509_NAME *n=NULL;
X509_NAME_ENTRY *ne=NULL;
int ok= -1,i,j;
+ int have_spkac= 0, have_req= 0;
long errline;
int nid;
@@ -1962,7 +1963,7 @@
/*
* Now create a dummy X509 request structure. We don't actually
- * have an X509 request, but we have many of the components
+ * have a true X509 request, but we have many of the components
* (a public key, various DN components). The idea is that we
* put these components into the right X509 request structure
* and we can use the same code as if you had a real X509 request.
@@ -1990,35 +1991,57 @@
if ((nid=OBJ_txt2nid(type)) == NID_undef)
{
- if (strcmp(type, "SPKAC") == 0)
+ have_spkac= strcmp(type, "SPKAC") == 0;
+ have_req= strcmp(type, "REQ") == 0;
+ if (have_spkac || have_req)
{
- spki_der=(unsigned char *)Malloc(
+ data_der=(unsigned char *)Malloc(
strlen(cv->value)+1);
- if (spki_der == NULL)
+ if (data_der == NULL)
{
BIO_printf(bio_err,"Malloc failure\n");
goto err;
}
- j = EVP_DecodeBlock(spki_der, (unsigned char
*)cv->value,
+ j = EVP_DecodeBlock(data_der, (unsigned char
+*)cv->value,
strlen(cv->value));
if (j <= 0)
{
- BIO_printf(bio_err, "Can't b64 decode SPKAC
structure\n");
+ BIO_printf(bio_err, "Can't b64 decode %s
+structure\n",type);
goto err;
}
- p=spki_der;
- spki = d2i_NETSCAPE_SPKI(&spki, &p, j);
- Free(spki_der);
- spki_der = NULL;
- if (spki == NULL)
+ p=data_der;
+ if (have_spkac)
{
- BIO_printf(bio_err,"unable to load Netscape
SPKAC structure\n");
- ERR_print_errors(bio_err);
- goto err;
+ spki = d2i_NETSCAPE_SPKI(&spki, &p, j);
+ if (spki == NULL)
+ {
+ BIO_printf(bio_err,"unable to load
+Netscape SPKAC structure\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ }
+ else
+ {
+ ireq = d2i_X509_REQ(&ireq, &p, j);
+ if (ireq == NULL)
+ {
+ BIO_printf(bio_err,"unable to load
+request\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
}
+ Free(data_der);
+ data_der = NULL;
+ continue;
+ }
+ else
+ {
+ BIO_printf(bio_err,"invalid item %s in file\n",type);
+ ERR_print_errors(bio_err);
+ goto err;
}
- continue;
+
}
j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
@@ -2037,32 +2060,62 @@
if (!X509_NAME_add_entry(n,ne,X509_NAME_entry_count(n),0))
goto err;
}
- if (spki == NULL)
- {
- BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
- infile);
- goto err;
- }
-
/*
- * Now extract the key from the SPKI structure.
+ * Now extract the key from the SPKI or REQ structure.
*/
- BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
-
- if ((pktmp=X509_PUBKEY_get(spki->spkac->pubkey)) == NULL)
+ if (have_req)
{
- BIO_printf(bio_err,"error unpacking SPKAC public key\n");
- goto err;
+ if (verbose)
+ X509_REQ_print(bio_err,ireq);
+
+ BIO_printf(bio_err,"Check that the request matches the signature\n");
+
+ if ((pktmp=X509_REQ_get_pubkey(ireq)) == NULL)
+ {
+ BIO_printf(bio_err,"error unpacking public key\n");
+ goto err;
+ }
+ i=X509_REQ_verify(ireq,pktmp);
+ if (i < 0)
+ {
+ ok=0;
+ BIO_printf(bio_err,"Signature verification problems....\n");
+ goto err;
+ }
+ if (i == 0)
+ {
+ ok=0;
+ BIO_printf(bio_err,"Signature did not match the certificate
+request\n");
+ goto err;
+ }
+ else
+ BIO_printf(bio_err,"Signature ok\n");
}
+ else if (have_spkac)
+ {
+ BIO_printf(bio_err,"Check that the SPKAC request matches the
+signature\n");
- j = NETSCAPE_SPKI_verify(spki, pktmp);
- if (j <= 0)
+ if ((pktmp=X509_PUBKEY_get(spki->spkac->pubkey)) == NULL)
+ {
+ BIO_printf(bio_err,"error unpacking SPKAC public key\n");
+ goto err;
+ }
+
+ j = NETSCAPE_SPKI_verify(spki, pktmp);
+ if (j <= 0)
+ {
+ BIO_printf(bio_err,"signature verification failed on SPKAC
+public key\n");
+ goto err;
+ }
+ BIO_printf(bio_err,"Signature ok\n");
+ }
+ else
{
- BIO_printf(bio_err,"signature verification failed on SPKAC public
key\n");
+ BIO_printf(bio_err,"Public key not found in %s\n",
+ infile);
goto err;
}
- BIO_printf(bio_err,"Signature ok\n");
X509_REQ_set_pubkey(req,pktmp);
EVP_PKEY_free(pktmp);
@@ -2071,7 +2124,8 @@
err:
if (req != NULL) X509_REQ_free(req);
if (parms != NULL) CONF_free(parms);
- if (spki_der != NULL) Free(spki_der);
+ if (ireq != NULL) X509_REQ_free(ireq);
+ if (data_der != NULL) Free(data_der);
if (spki != NULL) NETSCAPE_SPKI_free(spki);
if (ne != NULL) X509_NAME_ENTRY_free(ne);
--------------52F961108DCCE3CFC0375F40--
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]