Import of old SSLeay release: SSLeay 0.8.1b
diff --git a/demos/spkigen.c b/demos/spkigen.c
new file mode 100644
index 0000000..01fe625
--- /dev/null
+++ b/demos/spkigen.c
@@ -0,0 +1,160 @@
+/* NOCW */
+/* demos/spkigen.c
+ * 18-Mar-1997 - eay - A quick hack :-) 
+ * 		version 1.1, it would probably help to save or load the
+ *		private key :-)
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "err.h"
+#include "asn1.h"
+#include "objects.h"
+#include "evp.h"
+#include "x509.h"
+#include "pem.h"
+
+/* The following two don't exist in SSLeay but they are in here as
+ * examples */
+#define PEM_write_SPKI(fp,x) \
+	PEM_ASN1_write((int (*)())i2d_NETSCAPE_SPKI,"SPKI",fp,\
+			(char *)x,NULL,NULL,0,NULL)
+int SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+/* These are defined in the next version of SSLeay */
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type,char *key);
+#define RSA_F4	0x10001
+#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+					(char *)(rsa))
+
+int main(argc,argv)
+int argc;
+char *argv[];
+	{
+	RSA *rsa=NULL;
+	NETSCAPE_SPKI *spki=NULL;
+	EVP_PKEY *pkey=NULL;
+	char buf[128];
+	int ok=0,i;
+	FILE *fp;
+
+	pkey=EVP_PKEY_new();
+	 
+	if (argc < 2)
+		{
+		/* Generate an RSA key, the random state should have been seeded
+		 * with lots of calls to RAND_seed(....) */
+		fprintf(stderr,"generating RSA key, could take some time...\n");
+		if ((rsa=RSA_generate_key(512,RSA_F4,NULL)) == NULL) goto err;
+		}
+	else
+		{
+		if ((fp=fopen(argv[1],"r")) == NULL)
+			{ perror(argv[1]); goto err; }
+		if ((rsa=PEM_read_RSAPrivateKey(fp,NULL,NULL)) == NULL)
+			goto err;
+		fclose(fp);
+		}
+	
+	if (!EVP_PKEY_assign_RSA(pkey,rsa)) goto err;
+	rsa=NULL;
+
+	/* lets make the spki and set the public key and challenge */
+	if ((spki=NETSCAPE_SPKI_new()) == NULL) goto err;
+
+	if (!SPKI_set_pubkey(spki,pkey)) goto err;
+
+	fprintf(stderr,"please enter challenge string:");
+	fflush(stderr);
+	fgets(buf,120,stdin);
+	i=strlen(buf);
+	if (i > 0) buf[--i]='\0';
+	if (!ASN1_STRING_set((ASN1_STRING *)spki->spkac->challenge,
+		buf,i)) goto err;
+
+	if (!NETSCAPE_SPKI_sign(spki,pkey,EVP_md5())) goto err;
+	PEM_write_SPKI(stdout,spki);
+	if (argc < 2)
+		PEM_write_RSAPrivateKey(stdout,pkey->pkey.rsa,NULL,NULL,0,NULL);
+
+	ok=1;
+err:
+	if (!ok)
+		{
+		fprintf(stderr,"something bad happened....");
+		ERR_print_errors_fp(stderr);
+		}
+	NETSCAPE_SPKI_free(spki);
+	EVP_PKEY_free(pkey);
+	exit(!ok);
+	}
+
+/* This function is in the next version of SSLeay */
+int EVP_PKEY_assign(pkey,type,key)
+EVP_PKEY *pkey;
+int type;
+char *key;
+	{
+	if (pkey == NULL) return(0);
+	if (pkey->pkey.ptr != NULL)
+		{
+		if (pkey->type == EVP_PKEY_RSA)
+			RSA_free(pkey->pkey.rsa);
+		/* else memory leak */
+		}
+	pkey->type=type;
+	pkey->pkey.ptr=key;
+	return(1);
+	}
+
+/* While I have a 
+ * X509_set_pubkey() and X509_REQ_set_pubkey(), SPKI_set_pubkey() does
+ * not currently exist so here is a version of it.
+ * The next SSLeay release will probably have
+ * X509_set_pubkey(),
+ * X509_REQ_set_pubkey() and
+ * NETSCAPE_SPKI_set_pubkey()
+ * as macros calling the same function */
+int SPKI_set_pubkey(x,pkey)
+NETSCAPE_SPKI *x;
+EVP_PKEY *pkey;
+	{
+	int ok=0;
+	X509_PUBKEY *pk;
+	X509_ALGOR *a;
+	ASN1_OBJECT *o;
+	unsigned char *s,*p;
+	int i;
+
+	if (x == NULL) return(0);
+
+	if ((pk=X509_PUBKEY_new()) == NULL) goto err;
+	a=pk->algor;
+
+	/* set the algorithm id */
+	if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
+	ASN1_OBJECT_free(a->algorithm);
+	a->algorithm=o;
+
+	/* Set the parameter list */
+	if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL))
+		{
+		ASN1_TYPE_free(a->parameter);
+		a->parameter=ASN1_TYPE_new();
+		a->parameter->type=V_ASN1_NULL;
+		}
+	i=i2d_PublicKey(pkey,NULL);
+	if ((s=(unsigned char *)malloc(i+1)) == NULL) goto err;
+	p=s;
+	i2d_PublicKey(pkey,&p);
+	if (!ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err;
+	free(s);
+
+	X509_PUBKEY_free(x->spkac->pubkey);
+	x->spkac->pubkey=pk;
+	pk=NULL;
+	ok=1;
+err:
+	if (pk != NULL) X509_PUBKEY_free(pk);
+	return(ok);
+	}
+