2008-09-05 17:35:58 +04:00
#
2012-05-21 15:12:37 +04:00
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
2008-09-05 17:35:58 +04:00
2010-01-15 20:22:54 +03:00
from automation import Automation
2008-09-05 17:35:58 +04:00
import os
import re
2008-10-21 19:50:38 +04:00
import shutil
2008-09-05 17:35:58 +04:00
import sys
2008-12-05 19:52:25 +03:00
#expand DIST_BIN = __XPC_BIN_PATH__
2008-09-05 17:35:58 +04:00
#expand BIN_SUFFIX = __BIN_SUFFIX__
2009-01-19 00:44:43 +03:00
#expand PROFILE_DIR = __PROFILE_DIR__
2008-09-05 17:35:58 +04:00
#expand CERTS_SRC_DIR = __CERTS_SRC_DIR__
2010-01-15 20:22:54 +03:00
automation = Automation ( )
2008-09-05 17:35:58 +04:00
dbFiles = [
re . compile ( " ^cert[0-9]+ \ .db$ " ) ,
re . compile ( " ^key[0-9]+ \ .db$ " ) ,
re . compile ( " ^secmod \ .db$ " )
]
def unlinkDbFiles ( path ) :
for root , dirs , files in os . walk ( path ) :
for name in files :
for dbFile in dbFiles :
if dbFile . match ( name ) and os . path . exists ( os . path . join ( root , name ) ) :
os . unlink ( os . path . join ( root , name ) )
2008-10-21 19:50:38 +04:00
def dbFilesExist ( path ) :
for root , dirs , files in os . walk ( path ) :
for name in files :
for dbFile in dbFiles :
if dbFile . match ( name ) and os . path . exists ( os . path . join ( root , name ) ) :
return True
return False
2008-09-05 17:35:58 +04:00
def runUtil ( util , args , inputdata = None ) :
2009-01-12 22:23:28 +03:00
if inputdata :
proc = automation . Process ( [ util ] + args , env = automation . environment ( ) , stdin = automation . PIPE )
proc . communicate ( inputdata )
return proc . returncode
return automation . Process ( [ util ] + args , env = automation . environment ( ) ) . wait ( )
2008-09-05 17:35:58 +04:00
def createRandomFile ( randomFile ) :
import random
file = open ( randomFile , " wb " ) ;
for count in xrange ( 0 , 2048 ) :
file . write ( chr ( random . randint ( 0 , 255 ) ) )
file . close ( )
2009-01-19 00:44:43 +03:00
def createCertificateAuthority ( profileDir , srcDir ) :
2008-09-05 17:35:58 +04:00
certutil = DIST_BIN + " /certutil " + BIN_SUFFIX
pk12util = DIST_BIN + " /pk12util " + BIN_SUFFIX
2009-01-19 00:44:43 +03:00
tempDbDir = os . path . join ( profileDir , " .temp " )
2008-09-05 17:35:58 +04:00
if not os . path . exists ( tempDbDir ) :
os . mkdir ( tempDbDir )
pwfilePath = os . path . join ( tempDbDir , " .crtdbpw " )
rndfilePath = os . path . join ( tempDbDir , " .rndfile " )
pgoCAModulePathSrc = os . path . join ( srcDir , " pgoca.p12 " )
pgoCAPathSrc = os . path . join ( srcDir , " pgoca.ca " )
pwfile = open ( pwfilePath , " w " )
pwfile . write ( " \n " )
pwfile . close ( )
unlinkDbFiles ( tempDbDir )
# Create temporary certification database for CA generation
status = runUtil ( certutil , [ " -N " , " -d " , tempDbDir , " -f " , pwfilePath ] )
if status != 0 :
return status
createRandomFile ( rndfilePath ) ;
status = runUtil ( certutil , [ " -S " , " -d " , tempDbDir , " -s " , " CN=Temporary Certificate Authority, O=Mozilla Testing, OU=Profile Guided Optimization " , " -t " , " C,, " , " -x " , " -m " , " 1 " , " -v " , " 120 " , " -n " , " pgo temporary ca " , " -2 " , " -f " , pwfilePath , " -z " , rndfilePath ] , " Y \n 0 \n N \n " )
if status != 0 :
return status
status = runUtil ( certutil , [ " -L " , " -d " , tempDbDir , " -n " , " pgo temporary ca " , " -a " , " -o " , pgoCAPathSrc , " -f " , pwfilePath ] )
if status != 0 :
return status
status = runUtil ( pk12util , [ " -o " , pgoCAModulePathSrc , " -n " , " pgo temporary ca " , " -d " , tempDbDir , " -w " , pwfilePath , " -k " , pwfilePath ] )
if status != 0 :
return status
unlinkDbFiles ( tempDbDir )
os . unlink ( pwfilePath )
os . unlink ( rndfilePath )
os . rmdir ( tempDbDir )
return 0
2009-01-19 00:44:43 +03:00
def createSSLServerCertificate ( profileDir , srcDir ) :
2008-09-05 17:35:58 +04:00
certutil = DIST_BIN + " /certutil " + BIN_SUFFIX
pk12util = DIST_BIN + " /pk12util " + BIN_SUFFIX
2009-01-19 00:44:43 +03:00
pwfilePath = os . path . join ( profileDir , " .crtdbpw " )
rndfilePath = os . path . join ( profileDir , " .rndfile " )
pgoCAPath = os . path . join ( srcDir , " pgoca.p12 " )
2008-09-05 17:35:58 +04:00
pwfile = open ( pwfilePath , " w " )
pwfile . write ( " \n " )
pwfile . close ( )
2008-10-21 19:50:38 +04:00
if not dbFilesExist ( srcDir ) :
2009-01-19 00:44:43 +03:00
# Make sure all DB files from src are really deleted
2008-10-21 19:50:38 +04:00
unlinkDbFiles ( srcDir )
# Create certification database for ssltunnel
status = runUtil ( certutil , [ " -N " , " -d " , srcDir , " -f " , pwfilePath ] )
if status != 0 :
return status
status = runUtil ( pk12util , [ " -i " , pgoCAPath , " -w " , pwfilePath , " -d " , srcDir , " -k " , pwfilePath ] )
if status != 0 :
return status
2008-09-05 17:35:58 +04:00
# Generate automatic certificate
2009-01-19 00:44:43 +03:00
locations = automation . readLocations ( os . path . join ( profileDir , " server-locations.txt " ) )
2008-09-05 17:35:58 +04:00
locations . pop ( 0 )
locationsParam = " "
firstLocation = " "
for loc in locations :
if loc . scheme == " https " and " nocert " not in loc . options :
customCertOption = False
customCertRE = re . compile ( " ^cert=(?: \ w+) " )
for option in loc . options :
match = customCertRE . match ( option )
if match :
customCertOption = True
break
if not customCertOption :
if len ( locationsParam ) > 0 :
locationsParam + = " , "
locationsParam + = loc . host
if firstLocation == " " :
firstLocation = loc . host
if firstLocation == " " :
print " Nothing to generate, no automatic secure hosts specified "
else :
createRandomFile ( rndfilePath ) ;
2008-10-21 19:50:38 +04:00
runUtil ( certutil , [ " -D " , " -n " , " pgo server certificate " , " -d " , srcDir , " -z " , rndfilePath , " -f " , pwfilePath ] )
# Ignore the result, the certificate may not be present when new database is being built
2011-11-08 03:48:49 +04:00
status = runUtil ( certutil , [ " -S " , " -s " , " CN= %s " % firstLocation , " -t " , " Pu,, " , " -c " , " pgo temporary ca " , " -m " , " 2 " , " -8 " , locationsParam , " -v " , " 120 " , " -n " , " pgo server certificate " , " -d " , srcDir , " -z " , rndfilePath , " -f " , pwfilePath ] )
2008-09-05 17:35:58 +04:00
if status != 0 :
return status
os . unlink ( pwfilePath )
os . unlink ( rndfilePath )
return 0
if len ( sys . argv ) == 1 :
print " Specify --gen-server or --gen-ca "
sys . exit ( 1 )
if sys . argv [ 1 ] == " --gen-server " :
2009-01-19 00:44:43 +03:00
certificateStatus = createSSLServerCertificate ( PROFILE_DIR , CERTS_SRC_DIR )
2008-09-05 17:35:58 +04:00
if certificateStatus != 0 :
2009-02-11 01:05:27 +03:00
print " TEST-UNEXPECTED-FAIL | SSL Server Certificate generation "
2008-09-05 17:35:58 +04:00
sys . exit ( certificateStatus )
if sys . argv [ 1 ] == " --gen-ca " :
2009-01-19 00:44:43 +03:00
certificateStatus = createCertificateAuthority ( PROFILE_DIR , CERTS_SRC_DIR )
2008-09-05 17:35:58 +04:00
if certificateStatus != 0 :
2009-02-11 01:05:27 +03:00
print " TEST-UNEXPECTED-FAIL | Certificate Authority generation "
2008-09-05 17:35:58 +04:00
else :
print " \n \n "
print " =================================================== "
print " IMPORTANT: "
print " To use this new certificate authority in tests "
print " run ' make ' at testing/mochitest "
print " =================================================== "
sys . exit ( certificateStatus )
print " Invalid option specified "
sys . exit ( 1 )