3
########################################################################
5
# (c) by Michael Stroeder, michael@stroeder.com
6
########################################################################
10
########################################################################
11
# This script is used to revoke certificates from the command line
12
# ca-revoke.py -h prints usage of parameters.
13
########################################################################
15
import sys, string, os, smtplib, getopt
17
from time import time,localtime,strftime,mktime
19
def findoption(options,paramname):
25
def PrintUsage(ErrorMsg='',ErrorCode=1):
26
script_name = string.split(sys.argv[0],os.sep)[-1]
27
sys.stderr.write("""*** %s *** (C) by Michael Stroeder, 1999
34
Print out this message
37
Pathname of OpenSSL configuration file.
38
You may also use env variable OPENSSL_CONF.
39
Default: /etc/openssl/openssl.cnf
42
Specify directory containing the pyCA modules
43
You may also use env variable PYCALIB.
44
Default: /usr/local/pyca/pylib
47
Name of CA in section [ca] of OpenSSL config.
50
Serial number of certificate to revoke.
52
""" % (script_name,script_name))
54
sys.stderr.write('Error: %s\n' % ErrorMsg)
57
########################################################################
59
########################################################################
61
script_name=sys.argv[0]
64
options,args=getopt.getopt(sys.argv[1:],'h',['help','config=','pycalib=','name=','serial='])
65
except getopt.error,e:
68
if findoption(options,'-h')!=() or findoption(options,'--help')!=():
71
if findoption(options,'--config')!=():
72
opensslcnfname = findoption(options,'--config')[1]
74
opensslcnfname = os.environ.get('OPENSSL_CONF','/etc/openssl/openssl.cnf')
76
if not os.path.isfile(opensslcnfname):
77
PrintUsage('Config file %s not found.' % (opensslcnfname))
79
if findoption(options,'--pycalib')!=():
80
pycalib = findoption(options,'--pycalib')[1]
82
pycalib = os.environ.get('PYCALIB','/usr/local/pyca/pylib')
84
if not os.path.exists(pycalib) or not os.path.isdir(pycalib):
85
PrintUsage('Module directory %s not exists or not a directory.' % (pycalib))
87
sys.path.append(pycalib)
90
import openssl,charset
91
from openssl.db import \
93
DB_type,DB_exp_date,DB_rev_date,DB_serial,DB_file,DB_name,DB_number, \
94
DB_TYPE_REV,DB_TYPE_EXP,DB_TYPE_VAL, \
95
dbtime2tuple,GetEntriesbyDN,SplitDN
97
PrintUsage('Required pyCA modules not found in directory %s!' % (pycalib))
99
# Read the configuration file
100
if os.path.isfile('%s.pickle' % (opensslcnfname)):
101
# Try to read OpenSSL's config file from a pickled copy
102
f=open('%s.pickle' % (opensslcnfname),'rb')
104
# first try to use the faster cPickle module
105
from cPickle import load
107
from pickle import load
111
# Parse OpenSSL's config file from source
112
opensslcnf=openssl.cnf.OpenSSLConfigClass(opensslcnfname)
114
pyca_section = opensslcnf.data.get('pyca',{})
115
ca_names = opensslcnf.sectionkeys.get('ca',[])
117
openssl.bin_filename = pyca_section.get('OpenSSLExec','/usr/local/ssl/bin/openssl')
118
if not os.path.isfile(openssl.bin_filename):
119
sys.stderr.write('Did not find OpenSSL executable %s.\n' % (openssl.bin_filename))
122
if findoption(options,'--name')!=():
123
ca_name = findoption(options,'--name')[1]
124
if not ca_name in ca_names:
125
PrintUsage('Wrong CA name.\nCA names listed in the current configuration:\n%s.' % string.join(ca_names,', '))
127
PrintUsage('You have to provide a name of a CA definition.')
129
if findoption(options,'--serial')!=():
131
serial = string.atoi(findoption(options,'--serial')[1],16)
133
PrintUsage('No valid serial number.')
136
PrintUsage('You have to provide the serial number of the certificate you want to revoke.')
138
ca = opensslcnf.getcadata(ca_name)
140
sys.stdout.write('Searching database %s for certificate %x...\n' % (ca.database,serial))
141
ca_db = openssl.db.OpenSSLcaDatabaseClass(ca.database)
142
result = ca_db.GetEntrybySerial(serial)
145
sys.stdout.write("""Found the following certificate:
147
Distinguished Name: %s
148
""" % (result[DB_serial],charset.asn12iso(result[DB_name])))
150
if result[DB_type]==DB_TYPE_REV:
151
sys.stdout.write('Certificate already revoked since %s.\n' % strftime('%d.%m.%Y',localtime(mktime(dbtime2tuple(result[DB_rev_date])))))
153
elif result[DB_type]==DB_TYPE_EXP:
154
sys.stdout.write('Certificate already expired since %s.\n' % strftime('%d.%m.%Y',localtime(mktime(dbtime2tuple(result[DB_exp_date])))))
156
elif result[DB_type]==DB_TYPE_VAL:
157
sys.stdout.write('Valid until %s.\n\nRevoke the certificate? (y/n) ' % strftime('%d.%m.%Y',localtime(mktime(dbtime2tuple(result[DB_exp_date])))))
158
answer = sys.stdin.readline()
159
if string.lower(string.strip(answer))=='y':
161
sys.stdout.write('Certificate %x in %s marked as revoked.\n' % (serial,ca_name))
162
# CA's private key present <=> we are on the private CA system
163
if os.path.isfile(ca.certificate) and os.path.isfile(ca.private_key):
164
sys.stdout.write('Issue new CRL? (y/n) ')
165
answer = sys.stdin.readline()
166
if string.lower(string.strip(answer))=='y':
167
sys.stdout.write('Issueing new CRL %s.\n' % (ca.crl))
168
rc = os.system('%s ca -config %s -name %s -gencrl -out %s' % \
169
(openssl.bin_filename,opensslcnfname,ca.sectionname,ca.crl))
171
sys.stderr.write('Error %d creating CRL %s.\n' % (rc,ca.crl))
174
raise ValueError, 'Unknown type field %s in certificate database.' % result[DB_type]
177
PrintUsage('No certificate found in "%s" with serial %x.\n' % (ca_name,serial))