Commit f9a25931 authored by Ralf S. Engelschall's avatar Ralf S. Engelschall
Browse files

Add `openssl ca -revoke <certfile>' facility which revokes a certificate

specified in <certfile> by updating the entry in the index.txt file.
This way one no longer has to edit the index.txt file manually for
revoking a certificate. The -revoke option does the gory details now.

Submitted by: Massimiliano Pala <madwolf@openca.org>
Cleaned up and integrated by: Ralf S. Engelschall
parent 2f0cd195
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -5,6 +5,12 @@

 Changes between 0.9.2b and 0.9.3

  *) Add `openssl ca -revoke <certfile>' facility which revokes a certificate
     specified in <certfile> by updating the entry in the index.txt file.
     This way one no longer has to edit the index.txt file manually for
     revoking a certificate. The -revoke option does the gory details now.
     [Massimiliano Pala <madwolf@openca.org>, Ralf S. Engelschall]

  *) Fix `openssl crl -noout -text' combination where `-noout' killed the
     `-text' option at all and this way the `-noout -text' combination was
     inconsistent in `openssl crl' with the friends in `openssl x509|rsa|dsa'.
+181 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ static char *ca_usage[]={
" -preserveDN     - Don't re-order the DN\n",
" -batch          - Don't ask questions\n",
" -msie_hack      - msie modifications to handle all those universal strings\n",
" -revoke file    - Revoke a certificate (given in file)\n",
NULL
};

@@ -181,6 +182,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, EVP_MD *dgst,
	STACK *policy, TXT_DB *db, BIGNUM *serial, char *startdate,
	int days, int batch, int verbose, X509_REQ *req, char *ext_sect,
	LHASH *conf);
static int do_revoke(X509 *x509, TXT_DB *db);
static int check_time_format(char *str);
#else
static int add_oid_section();
@@ -199,6 +201,7 @@ static int certify_cert();
static int certify_spkac();
static void write_new_certificate();
static int do_body();
static int do_revoke();
static int check_time_format();
#endif

@@ -220,6 +223,7 @@ char **argv;
	int req=0;
	int verbose=0;
	int gencrl=0;
	int revoke=0;
	long crldays=0;
	long crlhours=0;
	long errorline= -1;
@@ -380,6 +384,12 @@ EF_ALIGNMENT=0;
			spkac_file = *(++argv);
			req=1;
			}
		else if (strcmp(*argv,"-revoke") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			revoke=1;
			}
		else
			{
bad:
@@ -1078,6 +1088,69 @@ bad:
		PEM_write_bio_X509_CRL(Sout,crl);
		}
	/*****************************************************************/
	if (revoke)
		{
        	in=BIO_new(BIO_s_file());
        	out=BIO_new(BIO_s_file());
        	if ((in == NULL) || (out == NULL))
                	{
                	ERR_print_errors(bio_err);
                	goto err;
                	}
        	if (infile == NULL) 
                	{
                	BIO_printf(bio_err,"no input files\n");
                	goto err;
                	}
		else
			{
                	if (BIO_read_filename(in,infile) <= 0)
                		{
                        	perror(infile);
                        	BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
                        	goto err;
                		}
                	x509=PEM_read_bio_X509(in,NULL,NULL);
                	if (x509 == NULL)
                		{
                        	BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
				goto err;
                		}
                	j=do_revoke(x509,db);

			strncpy(buf[0],dbfile,BSIZE-4);
                	strcat(buf[0],".new");
                	if (BIO_write_filename(out,buf[0]) <= 0)
                		{
                        	perror(dbfile);
                        	BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
                        	goto err;
                		}
                	j=TXT_DB_write(out,db);
                	if (j <= 0) goto err;
                	BIO_free(in);
                	BIO_free(out);
                	in=NULL;
                	out=NULL;
                	strncpy(buf[1],dbfile,BSIZE-4);
                	strcat(buf[1],".old");
                	if (rename(dbfile,buf[1]) < 0)
                		{
                        	BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
                        	perror("reason");
                        	goto err;
                		}
	                if (rename(buf[0],dbfile) < 0)
                		{
                        	BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
                        	perror("reason");
                        	rename(buf[1],dbfile);
                        	goto err;
                		}
                	BIO_printf(bio_err,"Data Base Updated\n"); 
		        }
		}
	/*****************************************************************/
	ret=0;
err:
	BIO_free(hex);
@@ -2068,3 +2141,111 @@ LHASH *hconf;
	}
	return 1;
}

static int do_revoke(x509,db)
X509 *x509;
TXT_DB *db;
{
        ASN1_UTCTIME *tm=NULL;
        char *row[DB_NUMBER],**rrow,**irow;
        int ok=-1,i;

        for (i=0; i<DB_NUMBER; i++)
                row[i]=NULL;
        row[DB_name]=X509_NAME_oneline(x509->cert_info->subject,NULL,0);
        row[DB_serial]=BN_bn2hex(ASN1_INTEGER_to_BN(x509->cert_info->serialNumber,NULL));
        if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
                {
                BIO_printf(bio_err,"Malloc failure\n");
                goto err;
                }
        rrow=TXT_DB_get_by_index(db,DB_name,row);
        if (rrow == NULL)
                {
                BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);

                /* We now just add it to the database */
                row[DB_type]=(char *)Malloc(2);

                tm=X509_get_notAfter(x509);
                row[DB_exp_date]=(char *)Malloc(tm->length+1);
                memcpy(row[DB_exp_date],tm->data,tm->length);
                row[DB_exp_date][tm->length]='\0';

                row[DB_rev_date]=NULL;

                /* row[DB_serial] done already */
                row[DB_file]=(char *)Malloc(8);

                /* row[DB_name] done already */

                if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
                        (row[DB_file] == NULL))
                        {
                        BIO_printf(bio_err,"Malloc failure\n");
                        goto err;
                        }
                strcpy(row[DB_file],"unknown");
                row[DB_type][0]='V';
                row[DB_type][1]='\0';

                if ((irow=(char **)Malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
                        {
                        BIO_printf(bio_err,"Malloc failure\n");
                        goto err;
                        }

                for (i=0; i<DB_NUMBER; i++)
                        {
                        irow[i]=row[i];
                        row[i]=NULL;
                        }
                irow[DB_NUMBER]=NULL;

                if (!TXT_DB_insert(db,irow))
                        {
                        BIO_printf(bio_err,"failed to update database\n");
                        BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
                        goto err;
                        }

                /* Revoke Certificate */
                do_revoke(x509,db);

                ok=1;
                goto err;

                }
        else if (index_serial_cmp(row,rrow))
                {
                BIO_printf(bio_err,"ERROR:no same serial number %s\n",
                           row[DB_serial]);
                goto err;
                }
        else if (rrow[DB_type][0]=='R')
                {
                BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
                           row[DB_serial]);
                goto err;
                }
        else
                {
                BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
                tm=X509_gmtime_adj(tm,0);
                rrow[DB_type][0]='R';
                rrow[DB_type][1]='\0';
                rrow[DB_rev_date]=(char *)Malloc(tm->length+1);
                memcpy(rrow[DB_rev_date],tm->data,tm->length);
                rrow[DB_rev_date][tm->length]='\0';
                }
        ok=1;
err:
        for (i=0; i<DB_NUMBER; i++)
                {
                if (row[i] != NULL) 
                        Free(row[i]);
                }
        ASN1_UTCTIME_free(tm);
        return(ok);
}