This is a multi-part message in MIME format.

------=_NextPart_000_0064_01C6E6F3.74497390
Content-Type: text/plain;
charset="US-ASCII"
Content-Transfer-Encoding: 7bit


Hi,

I'm submitting this patch as suggested below. This patch adds the x509_proxy
module to openssl which can create and printout proxy certificates.

I don't know if the licensing in the patch adheres to OpenSSL requirements,
If there are any problems please email me and I'll figure out how to modify
it appropriately.

Thank you,

--Ivan

PS -- the command used to create this (from two cvs trees) was:

diff -u -N -r -x CVS -x certs clean proxy, so it can be applied to a clean
cvs tree with:

(from within the checked out dir) patch -p1 -u < patchfile.


> -----Original Message-----
> From: owner-openssl-dev@openssl.org
> [mailtowner-openssl-dev@openssl.org] On Behalf Of Kyle Hamilton
> Sent: Friday, September 29, 2006 1:40 PM
> To: openssl-dev@openssl.org
> Subject: Re: Proxy module
>
> First off, you need to get rid of the "all rights reserved"
> copyright clause. Changing it so that it states you grant
> usage and distribution rights with OpenSSL under its license
> would be a good start. (Licensing, licensing, we all have to
> worry about it. )
>
> Next, create a diff -c (contextual diff) against the current
> CVS, including changes to the makefiles.
>
> Then, submit that diff as a patch against the current CVS to
> rt@openssl.org.
>
> (At least this is how I presume things should be done. This
> module may need to go into the contrib/ directory, as it does
> affect validation and thus security.)
>
> -Kyle H
>
> On 9/29/06, Ivan R. Judson wrote:
> >
> >
> > Hi,
> >
> > Awhile ago I mentioned wanting to get proxy support (RFC 3280, yes
> > it's expired, but in use) into openssl as simply as possible.
> >
> > I've built the attached module, that does what I wanted. What's the
> > best way to try and get this integrated into the standard

> distribution?
> >
> > Thanks,
> >
> > --Ivan
> >
> >
> >

>
>
> --
>
> -Kyle H
> __________________________________________________ ____________________
> OpenSSL Project http://www.openssl.org
> Development Mailing List openssl-dev@openssl.org
> Automated List Manager majordomo@openssl.org
>


------=_NextPart_000_0064_01C6E6F3.74497390
Content-Type: application/octet-stream;
name="patch.proxy"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="patch.proxy"

diff -N -r -u -x CVS -x certs clean/apps/Makefile proxy/apps/Makefile=0A=
--- clean/apps/Makefile 2006-10-03 14:17:29.000000000 -0500=0A=
+++ proxy/apps/Makefile 2006-10-03 13:48:23.000000000 -0500=0A=
@@ -37,7 +37,7 @@=0A=
=0A=
E_EXE=3D verify asn1pars req dgst dh dhparam enc passwd gendh errstr \=0A=
ca crl rsa rsautl dsa dsaparam ec ecparam \=0A=
- x509 genrsa gendsa genpkey s_server s_client speed \=0A=
+ x509 x509_proxy genrsa gendsa genpkey s_server s_client speed \=0A=
s_time version pkcs7 crl2pkcs7 sess_id ciphers nseq pkcs12 \=0A=
pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts=0A=
=0A=
@@ -53,7 +53,7 @@=0A=
E_OBJ=3D verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o =
gendh.o errstr.o \=0A=
ca.o pkcs7.o crl2p7.o crl.o \=0A=
rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o \=0A=
- x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \=0A=
+ x509.o x509_proxy.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o =
speed.o \=0A=
s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \=0A=
ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o \=0A=
spkac.o smime.o rand.o engine.o ocsp.o prime.o ts.o=0A=
@@ -61,7 +61,7 @@=0A=
E_SRC=3D verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c =
errstr.c ca.c \=0A=
pkcs7.c crl2p7.c crl.c \=0A=
rsa.c rsautl.c dsa.c dsaparam.c ec.c ecparam.c \=0A=
- x509.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c speed.c \=0A=
+ x509.c x509_proxy.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c =
speed.c \=0A=
s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \=0A=
ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c pkeyutl.c \=0A=
spkac.c smime.c rand.c engine.c ocsp.c prime.c ts.c=0A=
diff -N -r -u -x CVS -x certs clean/apps/progs.h proxy/apps/progs.h=0A=
--- clean/apps/progs.h 2006-07-08 19:53:44.000000000 -0500=0A=
+++ proxy/apps/progs.h 2006-10-03 13:29:22.000000000 -0500=0A=
@@ -20,6 +20,7 @@=0A=
extern int ec_main(int argc,char *argv[]);=0A=
extern int ecparam_main(int argc,char *argv[]);=0A=
extern int x509_main(int argc,char *argv[]);=0A=
+extern int x509_proxy_main(int argc,char *argv[]);=0A=
extern int genrsa_main(int argc,char *argv[]);=0A=
extern int gendsa_main(int argc,char *argv[]);=0A=
extern int genpkey_main(int argc,char *argv[]);=0A=
@@ -97,6 +98,7 @@=0A=
{FUNC_TYPE_GENERAL,"ecparam",ecparam_main},=0A=
#endif=0A=
{FUNC_TYPE_GENERAL,"x509",x509_main},=0A=
+ {FUNC_TYPE_GENERAL,"x509_proxy",x509_proxy_main},=0A=
#ifndef OPENSSL_NO_RSA=0A=
{FUNC_TYPE_GENERAL,"genrsa",genrsa_main},=0A=
#endif=0A=
diff -N -r -u -x CVS -x certs clean/apps/x509_proxy.c =
proxy/apps/x509_proxy.c=0A=
--- clean/apps/x509_proxy.c 1969-12-31 18:00:00.000000000 -0600=0A=
+++ proxy/apps/x509_proxy.c 2006-10-03 13:12:39.000000000 -0500=0A=
@@ -0,0 +1,385 @@=0A=
+/* apps/x509_proxy.c */
+/* Copyright (C) 2006 Ivan R. Judson (judson@mcs.anl.gov)
+ * All rights reserved.
+ *
+ * The licence and distribution terms for any publically available =
version or
+ * derivative of this code cannot be changed. i.e. this code cannot =
simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include
+#include
+#include
+#include
+#ifdef OPENSSL_NO_STDIO
+#define APPS_WIN16
+#endif
+#include "apps.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifndef OPENSSL_NO_RSA
+#include
+#endif
+
+#undef PROG
+#define PROG x509_proxy_main
+
+#undef POSTFIX
+#define POSTFIX ".srl"
+#define DEF_DAYS 1
+
+static const char *x509_proxy_usage[]=3D{
+ "usage: x509_proxy args\n",
+ " -inform arg - input format - default PEM (one of DER, NET or =
PEM)\n",
+ " -keyform arg - private key format - default PEM\n",
+ " -cert arg - input certificate\n",
+ " -key arg - input private key\n",
+ " -proxy arg - input proxy certificate\n",
+ " -out arg - output file - default stdout\n",
+ " -passin arg - private key password source\n",
+ " -days arg - How long till expiry of a signed certificate - =
def 30 days\n",
+ " -md2/-md5/-sha1/-mdc2 - digest to use\n",
+ " -create - create a proxy certificate\n",
+ " -info - print the certificate in text form\n",
+ NULL
+};
+
+#ifndef OPENSSL_NO_RSA
+static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb);
+#endif
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+{
+ char *proxyfile=3DNULL, *outfile=3DNULL, *keyfile=3DNULL, =
*certfile=3DNULL;
+ char *alias=3DNULL, *passin=3DNULL, *passargin=3DNULL;
+ const char **pp;
+ int ret=3D1, num, badops=3D0, informat, keyformat, info=3D0;
+ int create=3D0, days=3DDEF_DAYS, modulus=3D512;
+ unsigned long nmflag =3D 0, certflag =3D 0;
+ const EVP_MD *md_alg, *digest=3DEVP_md5();
+ ASN1_INTEGER *sno =3D NULL;
+ BIO *out=3DNULL, *STDout=3DNULL;
+ ENGINE *e =3D NULL;
+ EVP_PKEY *userkey=3DNULL;
+ STACK_OF(ASN1_OBJECT) *trust =3D NULL, *reject =3D NULL;
+ X509 *usercert=3DNULL, *proxy=3DNULL;
+#ifndef OPENSSL_NO_ENGINE
+ char *engine=3DNULL;
+#endif
+
+ apps_startup();
+
+ if (bio_err =3D=3D NULL)
+ bio_err=3DBIO_new_fp(stderr,BIO_NOCLOSE);
+
+ if (!load_config(bio_err, NULL))
+ goto end;
+ STDout=3DBIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio =3D BIO_new(BIO_f_linebuffer());
+ STDout =3D BIO_push(tmpbio, STDout);
+ }
+#endif
+
+ informat=3DFORMAT_PEM;
+ keyformat=3DFORMAT_PEM;
+
+ argc--;
+ argv++;
+ num=3D0;
+
+ while (argc >=3D 1) {
+ if (strcmp(*argv,"-inform") =3D=3D 0) {
+ if (--argc < 1) goto bad;
+ informat=3Dstr2fmt(*(++argv));
+ } else if (strcmp(*argv,"-keyform") =3D=3D 0) {
+ if (--argc < 1) goto bad;
+ keyformat=3Dstr2fmt(*(++argv));
+ } else if (strcmp(*argv,"-days") =3D=3D 0) {
+ if (--argc < 1) goto bad;
+ days=3Datoi(*(++argv));
+ if (days =3D=3D 0) {
+ BIO_printf(STDout,"bad number of days\n");
+ goto bad;
+ }
+ } else if (strcmp(*argv,"-passin") =3D=3D 0) {
+ if (--argc < 1) goto bad;
+ passargin=3D *(++argv);
+ } else if (strcmp(*argv,"-cert") =3D=3D 0) {
+ if (--argc < 1) goto bad;
+ certfile=3D *(++argv);
+ } else if (strcmp(*argv,"-key") =3D=3D 0) {
+ if (--argc < 1) goto bad;
+ keyfile=3D *(++argv);
+ } else if (strcmp(*argv,"-proxy") =3D=3D 0) {
+ if (--argc < 1) goto bad;
+ proxyfile=3D *(++argv);
+ } else if (strcmp(*argv,"-out") =3D=3D 0) {
+ if (--argc < 1) goto bad;
+ outfile=3D *(++argv);
+ } else if (strcmp(*argv,"-create") =3D=3D 0)
+ create =3D ++num;
+ else if (strcmp(*argv,"-info") =3D=3D 0)
+ info =3D ++num;
+ else if ((md_alg=3DEVP_get_digestbyname(*argv + 1)))
+ digest=3Dmd_alg;
+ else {
+ BIO_printf(bio_err,"unknown option %s\n",*argv);
+ badops=3D1;
+ break;
+ }
+ =09
+ argc--;
+ argv++;
+ }
+
+ if (badops) {
+ bad:
+ for (pp=3Dx509_proxy_usage; (*pp !=3D NULL); pp++)
+ BIO_printf(bio_err,"%s",*pp);
+ goto end;
+ }
+
+ /* Initialization */
+#ifndef OPENSSL_NO_ENGINE
+ e =3D setup_engine(bio_err, engine, 0);
+#endif
+
+ if (create)
+ app_RAND_load_file(NULL, bio_err, 0);
+ =20
+ ERR_load_crypto_strings();
+ =20
+ if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
+ BIO_printf(bio_err, "Error getting password\n");
+ goto end;
+ }
+
+ /* Create output file or filehandle */
+ OBJ_create("2.99999.3",
+ "SET.ex3","SET x509v3 extension 3");
+ =20
+ out=3DBIO_new(BIO_s_file());
+ =20
+ if (out =3D=3D NULL) {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ =20
+ if (outfile =3D=3D NULL) {
+ BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+ {
+ BIO *tmpbio =3D BIO_new(BIO_f_linebuffer());
+ out =3D BIO_push(tmpbio, out);
+ }
+#endif
+ } else {
+ if (BIO_write_filename(out,outfile) <=3D 0) {
+ perror(outfile);
+ goto end;
+ }
+ }
+
+ /* If print the proxy, print it! */
+ if (info) {
+ proxy =3D load_cert(bio_err, proxyfile, informat, NULL, e, =
"Certificate");
+ X509_print_ex(out, proxy, nmflag, certflag);
+ }
+
+ /* If create a new proxy, do that... */
+ if (create) {
+ long tout =3D 60*60*12*days;
+ unsigned long f4=3DRSA_F4;
+ EVP_PKEY *proxykey =3D EVP_PKEY_new(), *signkey =3D EVP_PKEY_new();
+ LHASH *hash =3D lh_new(NULL, NULL);
+ X509V3_CTX ctx;
+ X509_EXTENSION *ku_ext, *pci_ext;
+ X509_NAME *sname=3DNULL;
+ X509_NAME_ENTRY *cn=3DNULL;
+ RSA *rsa =3D RSA_new();
+ BN_GENCB cb;
+ BIGNUM *bn =3D BN_new();
+ =20
+ /* Create a new X509 Certificate to be the proxy */
+ proxy=3DX509_new();
+
+ /* Load the certificate */
+ if (certfile) {
+ usercert =3D load_cert(bio_err, certfile, informat, NULL, =
e,"Certificate");
+ if (usercert =3D=3D NULL) goto end;
+ while(X509_get_ext_count(usercert) > 0)=20
+ X509_delete_ext(usercert, 0);
+ }
+
+ /* Load the private key */
+ if (keyfile) {
+ userkey =3D load_key(bio_err, keyfile, FORMAT_PEM, 0,=20
+ NULL, e, "Private Key");
+ }
+ =20
+ /* Generate a new RSA private key */
+ BN_GENCB_set(&cb, genrsa_cb, bio_err);
+ BIO_printf(bio_err,
+ "Generating RSA private key, %d bit long modulus\n",
+ modulus);
+ if (!BN_set_word(bn, f4) ||=20
+ !RSA_generate_key_ex(rsa, modulus, bn, &cb) ||
+ !EVP_PKEY_assign_RSA(proxykey, rsa)) {
+ BN_free(bn);
+ RSA_free(rsa);
+ goto end;
+ }
+
+ /* Create the fancy proxy extensions */
+ X509V3_set_conf_lhash(&ctx, hash);
+ ku_ext =3D X509V3_EXT_conf(hash, &ctx, "keyUsage",=20
+ "Digital Signature, Key Encipherment, Data Encipherment");
+ X509_EXTENSION_set_critical(ku_ext, 1);
+
+ pci_ext =3D X509V3_EXT_conf(hash, &ctx, "proxyCertInfo",
+ "critical, language:Inherit all");
+ X509_EXTENSION_set_critical(pci_ext, 1);
+
+ /* Get a serial number, creating one if necessary */
+ if (sno) {
+ if (!X509_set_serialNumber(proxy, sno)) goto end;
+ } else {
+ if (!rand_serial(NULL, X509_get_serialNumber(proxy))) goto end;
+ }
+
+ /* Assign the bits to the proxy */
+ if (!X509_set_pubkey(proxy, proxykey)) goto end;
+ if (!X509_set_version(proxy, 2)) goto end;
+ if (X509_gmtime_adj(X509_get_notBefore(proxy), (long)0) =3D=3D =
NULL) goto end;
+ if (X509_gmtime_adj(X509_get_notAfter(proxy),(long)36 00*24*days) =
=3D=3D NULL)=20
+ goto end;
+ sname =3D X509_NAME_dup(X509_get_subject_name(usercert));
+ if (!X509_NAME_add_entry_by_txt(sname, "commonName", MBSTRING_ASC,=20
+ i2s_ASN1_INTEGER(NULL,=20
+ X509_get_serialNumber(proxy)),
+ -1, -1, 0))
+ goto end;
+ if (!X509_set_issuer_name(proxy, X509_get_subject_name(usercert)))=20
+ goto end;
+ if (!X509_set_subject_name(proxy, sname))=20
+ goto end;
+ if (!X509_add_ext(proxy, ku_ext, 1)) goto end;
+ if (!X509_add_ext(proxy, pci_ext, 1)) goto end;
+
+ /* Assign the user supplied private key to the signing key */
+ EVP_PKEY_assign_RSA(signkey, EVP_PKEY_get1_RSA(userkey));
+
+ /* sign the proxy */
+ if (!X509_sign(proxy, signkey, digest)) {
+ ERR_print_errors(bio_err);
+ RSA_free(rsa);
+ EVP_PKEY_free(proxykey);
+ goto end;
+ }
+
+ /* Print out the proxy */
+ if (!PEM_write_bio_X509(out, proxy)) {
+ BIO_printf(bio_err,"Unable to write proxy certificate\n");
+ ERR_print_errors(bio_err);
+ }
+ if (!PEM_write_bio_RSAPrivateKey(out, rsa, NULL, NULL, 0, NULL, =
NULL)) {
+ BIO_printf(bio_err,"Unable to write private key\n");
+ ERR_print_errors(bio_err);
+ }
+ if (!PEM_write_bio_X509(out, usercert)) {
+ BIO_printf(bio_err,"Unable to write user certificate\n");
+ ERR_print_errors(bio_err);
+ }
+
+ RSA_free(rsa);
+ }
+
+ ret=3D0;
+
+ /* Cleanup */
+ end:
+ if (create)
+ app_RAND_write_file(NULL, bio_err);
+ OBJ_cleanup();
+ BIO_free_all(out);
+ BIO_free_all(STDout);
+ X509_free(usercert);
+ EVP_PKEY_free(userkey);
+ ASN1_INTEGER_free(sno);
+ if (passin) OPENSSL_free(passin);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+}
+
+static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, =
int create)
+{
+ char *buf =3D NULL, *p;
+ ASN1_INTEGER *bs =3D NULL;
+ BIGNUM *serial =3D NULL;
+ size_t len;
+
+ len =3D ((serialfile =3D=3D NULL)
+ ?(strlen(CAfile)+strlen(POSTFIX)+1)
+ strlen(serialfile)))+1;
+ buf=3DOPENSSL_malloc(len);
+ if (buf =3D=3D NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; =
}
+ if (serialfile =3D=3D NULL)
+ {
+ BUF_strlcpy(buf,CAfile,len);
+ for (p=3Dbuf; *p; p++)
+ if (*p =3D=3D '.')
+ {
+ *p=3D'\0';
+ break;
+ }
+ BUF_strlcat(buf,POSTFIX,len);
+ }
+ else
+ BUF_strlcpy(buf,serialfile,len);
+
+ serial =3D load_serial(buf, create, NULL);
+ if (serial =3D=3D NULL) goto end;
+
+ if (!BN_add_word(serial,1))
+ { BIO_printf(bio_err,"add_word failure\n"); goto end; }
+
+ if (!save_serial(buf, NULL, serial, &bs)) goto end;
+
+ end:
+ if (buf) OPENSSL_free(buf);
+ BN_free(serial);
+ return bs;
+}
+
+#ifndef OPENSSL_NO_RSA
+static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb)
+{
+ char c=3D'*';
+
+ if (p =3D=3D 0) c=3D'.';
+ if (p =3D=3D 1) c=3D'+';
+ if (p =3D=3D 2) c=3D'*';
+ if (p =3D=3D 3) c=3D'\n';
+ BIO_write(cb->arg,&c,1);
+ (void)BIO_flush(cb->arg);
+#ifdef LINT
+ p=3Dn;
+#endif
+ return 1;
+}
+#endif
+

------=_NextPart_000_0064_01C6E6F3.74497390--

__________________________________________________ ____________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-dev@openssl.org
Automated List Manager majordomo@openssl.org