This file is indexed.

/usr/sbin/ca-make.py is in pyca 20031119-0.1ubuntu1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
#!/usr/bin/python

"""
ca-make.py - boot-strap of certificate authorities
(c) by Michael Stroeder, michael@stroeder.com

This script creates if non-existent (in the order given below,
does not overwrite existing files with file length > 0):

Directory structure:
dir		Where everything is kept
certs		Where the issued certs are kept
new_certs_dir	default place for new certs.
crl_dir		Where the issued crl are kept

Files:
database	database index file.
serial		The current serial number

Certificate files:
private_key	The private key of the CA
certificate	The CA certificate
"""

__version__ = '0.6.6'

import sys, string, os, stat, pwd, grp, getopt, time

def filenotvalid(pathname):
  return not os.path.isfile(pathname) or os.stat(pathname)[stat.ST_SIZE]==0

def CheckedMakeDir(dirname,perms=0,uid=0,gid=0):

  if not dirname:
    return

  if os.path.exists(dirname):
    # Directory does already exist
    if not os.path.isdir(dirname):
      sys.stderr.write('Warning: %s already exists but is no directory.\n' % (dirname))
  else:
    # Create directory 
    try:
      os.makedirs(dirname)
      sys.stdout.write('Created directory %s\n' % (dirname))
    except OSError:
      sys.stderr.write('Error: Could not create directory %s.\n' % (dirname))
      return

  # Get current file stat info
  fstat = os.stat(dirname)

  if perms:
    os.chmod(dirname,perms)
    sys.stdout.write('Changed permissions of %s to %o\n' % (dirname,perms))

  if (uid and fstat[stat.ST_UID]!=uid) or \
     (gid and fstat[stat.ST_GID]!=gid):
    if not uid:
      uid=fstat[stat.ST_UID]
    if not gid:
      gid=pwd.getpwuid(uid)[3]
    os.chown(dirname,uid,gid)
    sys.stdout.write('Changed owner/group of %s to %s.%s\n' % (dirname,pwd.getpwuid(uid)[0],grp.getgrgid(gid)[0]))

def findoption(options,paramname):
  for i in options:
    if i[0]==paramname:
      return i
  return ()

def PrintUsage(ErrorMsg='',ErrorCode=1):
  script_name = string.split(sys.argv[0],os.sep)[-1]
  sys.stderr.write("""*** %s *** (C) by Michael Stroeder, 1999

usage: %s [options]

Options:

  -h or --help
        Print out this message

  --config=[pathname]
	Pathname of OpenSSL configuration file.
        You may also use env variable OPENSSL_CONF.
	Default: /etc/pyca/openssl.cnf

  --pycalib=[directory]
        Specify directory containing the pyCA modules
	Default: /usr/share/pyca/pylib

""" % (script_name,script_name))
  if ErrorMsg:
    sys.stderr.write('Error: %s\n' % ErrorMsg)
  sys.exit(ErrorCode)

########################################################################
#                              Main
########################################################################

script_name=sys.argv[0]

try:
  options,args=getopt.getopt(sys.argv[1:],'h',['help','config=','pycalib='])
except getopt.error,e:
  PrintUsage(str(e))

if findoption(options,'-h')!=() or findoption(options,'--help')!=():
  PrintUsage()

if findoption(options,'--config')!=():
  opensslcnfname = findoption(options,'--config')[1]
else:
  opensslcnfname = os.environ.get('OPENSSL_CONF','/etc/pyca/openssl.cnf')

if not os.path.isfile(opensslcnfname):
  PrintUsage('Config file %s not found.' % (opensslcnfname))

if findoption(options,'--pycalib')!=():
  pycalib = findoption(options,'--pycalib')[1]
else:
  pycalib = os.environ.get('PYCALIB','/usr/share/pyca/pylib')

if not os.path.exists(pycalib) or not os.path.isdir(pycalib):
  PrintUsage('Module directory %s not exists or not a directory.' % (pycalib))

sys.path.append(pycalib)

try:
  import openssl, charset
except ImportError:
  PrintUsage('Required pyCA modules not found in directory %s!' % (pycalib))

# Read the configuration file
if os.path.isfile('%s.pickle' % (opensslcnfname)):
  # Try to read OpenSSL's config file from a pickled copy
  f=open('%s.pickle' % (opensslcnfname),'rb')
  try:
    # first try to use the faster cPickle module
    from cPickle import load
  except ImportError:
    from pickle import load
  opensslcnf=load(f)
  f.close()
else:
  # Parse OpenSSL's config file from source
  opensslcnf=openssl.cnf.OpenSSLConfigClass(opensslcnfname)

pyca_section = opensslcnf.data.get('pyca',{})

openssl.bin_filename = pyca_section.get('OpenSSLExec','/usr/bin/openssl')
if not os.path.isfile(openssl.bin_filename):
  PrintUsage('Did not find OpenSSL executable %s.' % (openssl.bin_filename))

OpenSSLExec = openssl.bin_filename

currentusername = pwd.getpwuid(os.getuid())[0]

# Getting UIDs
# Set current UID as default
uidCAAdmin    = pwd.getpwnam(pyca_section.get('userCAAdmin',currentusername))[2]
uidMailDaemon = pwd.getpwnam(pyca_section.get('userMailDaemon',currentusername))[2]
uidWWWRun     = pwd.getpwnam(pyca_section.get('userWWWRun',currentusername))[2]
gidCAAdmin    = pwd.getpwuid(uidCAAdmin)[3]
gidMailDaemon = pwd.getpwuid(uidMailDaemon)[3]
gidWWWRun     = pwd.getpwuid(uidWWWRun)[3]

ca_names = opensslcnf.sectionkeys.get('ca',[])


sys.stdout.write("""
#############################################################
# Create directories and various files
#############################################################
""")

for ca_name in ca_names:

  sys.stdout.write('\nProcessing %s\n' % ca_name)
  ca = opensslcnf.getcadata(ca_name)
    
  # Create sub-directories
  CheckedMakeDir(ca.dir,perms=0755,uid=uidCAAdmin,gid=gidCAAdmin)
  CheckedMakeDir(ca.certs,perms=0755,uid=uidCAAdmin,gid=gidCAAdmin)
  CheckedMakeDir(ca.new_certs_dir,perms=0700,uid=uidCAAdmin,gid=gidCAAdmin)
  CheckedMakeDir(ca.crl_dir,perms=0755,uid=uidCAAdmin,gid=gidCAAdmin)

  if ca.pend_reqs_dir==ca.new_reqs_dir:
    CheckedMakeDir(ca.new_reqs_dir,perms=0370,uid=uidWWWRun,gid=gidCAAdmin)
  else:
    CheckedMakeDir(ca.pend_reqs_dir,perms=0370,uid=uidWWWRun,gid=gidMailDaemon)
    CheckedMakeDir(ca.new_reqs_dir,perms=0370,uid=uidMailDaemon,gid=gidCAAdmin)

  CheckedMakeDir(ca.old_reqs_dir,perms=0700,uid=uidCAAdmin,gid=gidCAAdmin)

  CheckedMakeDir(os.path.dirname(ca.certificate),perms=0755,uid=uidCAAdmin,gid=gidCAAdmin)
  if os.path.isfile(ca.certificate):
    # In any case we set permission and ownership of
    # CA certificate file if already existent
    os.chown(ca.certificate,uidCAAdmin,gidCAAdmin)
    os.chmod(ca.certificate,0444)

  CheckedMakeDir(os.path.dirname(ca.private_key),perms=0700,uid=uidCAAdmin,gid=gidCAAdmin)
  if os.path.isfile(ca.private_key):
    # In any case we set permission and ownership of
    # CA private key file if existent
    os.chown(ca.private_key,uidCAAdmin,gidCAAdmin)
    os.chmod(ca.private_key,0400)

  # database: database index file
  if not os.path.isfile(ca.database):
    sys.stdout.write('Creating database file %s\n' % (ca.database))
    file=open(ca.database,'w')
    file.write('')
    file.close()
  os.chown(ca.database,uidCAAdmin,gidCAAdmin)
  os.chmod(ca.database,0644)

  # serial: next serial number for issueing certificates
  if filenotvalid(ca.serial):
    sys.stdout.write('Creating serial file %s\n' % (ca.serial))
    file=open(ca.serial,'w')
    file.write('01\n')
    file.close()
  os.chown(ca.serial,uidCAAdmin,gidCAAdmin)
  os.chmod(ca.serial,0600)

os.setgid(gidCAAdmin)
os.setuid(uidCAAdmin)

sys.stdout.write("""
#############################################################
# create self-signed CA certs or certificate requests
#############################################################\n
Give passwords for each CAs here.
""")

subca = []

for ca_name in ca_names:

  sys.stdout.write('\nProcessing %s\n' % ca_name)
  ca = opensslcnf.getcadata(ca_name)
    
  if ca.signedby:
    # Add CA to list of sub-CAs to be signed late
    subca.append(ca_name)

  if filenotvalid('%s-req' % ca.certificate) and filenotvalid(ca.private_key):
    sys.stdout.write('Creating certificate request %s with private key %s.\n' % (ca.certificate,ca.private_key))
    if not ca.ca_reqfile:
      ca.ca_reqfile = ca.ca_x509_extfile
      if not ca.ca_reqfile:
        ca.ca_reqfile = opensslcnfname
    rc = os.system('%s req -config %s -new -outform pem -out %s-req -keyout %s' % \
                   (OpenSSLExec,ca.ca_reqfile,ca.certificate,ca.private_key))
    os.chmod(ca.private_key,0400)
    if rc:
      sys.stderr.write('Error %d creating CA cert request %s-req.\n' % (rc,ca.certificate))

  if filenotvalid(ca.certificate) and not ca.signedby:
    sys.stdout.write('How many days should this certificate be valid (minimum=%d, default=%d days): ' % (ca.default_days+1,2*ca.default_days+1))
    days = string.strip(sys.stdin.readline())
    if not days:
      days = 2*ca.default_days+1
    rc = os.system('%s x509 -req -inform pem -in %s-req -outform pem -out %s -signkey %s -days %s -extfile %s' % \
                   (OpenSSLExec,ca.certificate,ca.certificate,ca.private_key,days,ca.ca_x509_extfile))
    if rc:
      sys.stderr.write('Error %d self-signing CA cert %s.\n' % (rc,ca.certificate))


if subca:
  sys.stdout.write("""
#############################################################
# Create certs of sub-CAs
#############################################################\n
Use passwords of parent CAs here.\n
""")

  for ca_name in subca:
    sys.stdout.write('\nProcessing %s\n' % ca_name)
    # Get the sub-CA's config data
    subca = opensslcnf.getcadata(ca_name)
    # Check if signedby points to a valid CA section name
    if not subca.signedby in ca_names:
      sys.stderr.write('CA name "%s" given in signedby parameter of section [%s] not found.\n' % (subca.signedby,subca.sectionname))
      sys.exit(1)
    # Get the issuer's CA config data
    ca = opensslcnf.getcadata(subca.signedby)
    # Check if issuer's certificate and key files are present
    if filenotvalid(ca.certificate) or filenotvalid(ca.private_key):
      sys.stderr.write("""CA certificate or key file of issuer %s not found or zero-length.
      Check the files %s and %s.
      """ % (subca.signedby,ca.certificate,ca.private_key))
      sys.exit(1)
    # Check if issuer certificate is valid at current time
    gmt = time.time()
    ca_cert = openssl.cert.X509CertificateClass(ca.certificate)
    if gmt+86400*ca.default_days>ca_cert.notAfter_secs:
      sys.stderr.write("""Certificate of issueing parent CA "%s" is not valid until %s.
      You can either set parameter default_days<=%d in section [%s] or
      issue a new parent CA cert.
      """ % (ca.name,time.strftime('%Y-%m-%d %H:%M',time.gmtime(gmt+86400*ca.default_days)),(ca_cert.notAfter_secs-gmt)/86400,ca.sectionname))
      sys.exit(1)
    # Create the new sub-CA certificate if there's no older file in the way
    if filenotvalid(subca.certificate):
      sys.stdout.write('Creating sub-CA certificate %s with issuer "%s".\n' % (subca.certificate,ca.name))
      rc = os.system('%s x509 -req -inform pem -in %s-req -outform pem -out %s -CA %s -CAkey %s -CAserial %s -days %s -extfile %s' % \
                     (OpenSSLExec,subca.certificate,subca.certificate,ca.certificate,ca.private_key,ca.serial,ca.default_days,subca.ca_x509_extfile))
      if rc:
	sys.stderr.write('Error %d issueing CA cert %s.\n' % (rc,ca.certificate))
    else:
      sys.stdout.write('Sub-CA certificate file %s already exists. Skipping...\n' % (subca.certificate))

sys.stdout.write("""
#############################################################
# Verifying CA certs
#############################################################\n
""")

for ca_name in ca_names:

  ca = opensslcnf.getcadata(ca_name)

  if ca.signedby:
    if ca.signedby in ca_names:
      parentca = opensslcnf.getcadata(ca.signedby)
    else:
      parentca = None
      sys.stderr.write('CA name "%s" given in signedby parameter of section [%s] not found.\n' % (subca.signedby,subca.sectionname))
  else:
    parentca = ca

  if not (filenotvalid(ca.certificate) or filenotvalid(parentca.certificate)):

    sys.stdout.write('Verifying sub-CA certificate %s with issuer certificate %s.\n' % (ca.certificate,parentca.certificate))
    rc = os.system('%s verify -verbose -CAfile %s %s' % \
                   (OpenSSLExec,parentca.certificate,ca.certificate))
    if rc:
      sys.stderr.write('Error %d verifying CA cert %s.\n' % (rc,ca.certificate))

    ca_cert = openssl.cert.X509CertificateClass(ca.certificate)

    if not ca_cert.subject.has_key('CN'):
      sys.stderr.write('CA certificate %s has no CN attribute.\nThis might cause weird problems with some software.\n' % (ca.certificate))

    for subject_attr in ca_cert.subject.keys():
      if not charset.is_ascii(charset.asn12iso(ca_cert.subject[subject_attr])):
        sys.stderr.write('CA certificate %s has NON-ASCII attribute %s.\nThis might cause weird problems with some software.\n' % (ca.certificate,subject_attr))

  else:
    sys.stderr.write('Certificate file %s or %s not found.\n' % (ca.certificate,parentca.certificate))