1. Certificado Digital – OpenSSL
Esse tutorial descreverá como configurar o VisualSVN Server para utilizar certificados digitais e assegurar que não haja acessos indevidos.
O objetivo é ter um certificado digital para cada usuário possibilitando o acesso dos mesmos ao repositório svn.
Para a criação desses certificados digitais será utilizado a ferramenta OpenSSL que já vem incluso na instalação do VisualSVN Server.
1.1. Preparando o Ambiente
Antes de iniciar a criação dos certificados será necessário preparar um ambiente configurando-o adequadamente.
Como o openssl será utilizado e é uma ferramenta de linha de comandos, utilizaremos o prompt de comandos para a execução dos scripts necessários.
Para isso, abra um prompt de comandos com permissões de administrador (necessário no Windows Vista/7) e vá até o diretório bin da instalação do VisualSVN (provavelmente em C:\Program Files\VisualSVN Server\bin).
1.1.1. Estrutura de Diretórios/Arquivos
a) Dentro do diretório bin deve-ser criar a seguinte estrutura de diretórios:
Você pode criar essa estrutura de diretórios com o Windows Explorer ou com o próprio prompt de comandos.
b) Crie um arquivo chamado Serial (sem extensão) com o conteúdo “01” (sem as aspas duplas) e grave-o no diretório .\Cert\demoCA\.
c) Crie um arquivo chamado Index.txt (vazio) gravando-o no diretório .\Cert\demoCA\.
O script MS-DOS Batch abaixo cria a estrutura de diretórios.
@ECHO OFF
IF NOT EXIST "%ProgramFiles%\VisualSVN Server\bin" GOTO VSVN_NO_EXIT
SET VSVN=%ProgramFiles%\VisualSVN Server\bin
IF NOT EXIST "%VSVN%\Cert" GOTO BIN_CLEAR
DEL /S /Q /F "%VSVN%\Cert\*.*" > .\Log.txt
CHOICE /N /C:Y /T:1 /D:Y > .\Log.txt
RD /S /Q "%VSVN%\Cert"
:BIN_CLEAR
MD "%VSVN%\Cert"
MD "%VSVN%\Cert\demoCA"
MD "%VSVN%\Cert\demoCA\certs"
MD "%VSVN%\Cert\demoCA\crt"
MD "%VSVN%\Cert\demoCA\newcerts"
MD "%VSVN%\Cert\demoCA\private"
ECHO 01>"%VSVN%\Cert\demoCA\serial"
@ECHO OFF>"%VSVN%\Cert\demoCA\index.txt"
COPY .\openssl.config "%VSVN%\Cert" > .\Log.txt
COPY .\genCA.bat "%VSVN%\Cert" > .\Log.txt
COPY .\genClient.bat "%VSVN%\Cert" > .\Log.txt
COPY .\genServer.bat "%VSVN%\Cert" > .\Log.txt
DEL /Q .\Log.txt
%SystemDrive%
CD "%ProgramFiles%\VisualSVN Server\bin\Cert"
GOTO FIM
:VSVN_NO_EXIT
ECHO Diretório "%ProgramFiles%\VisualSVN Server\bin" não existente.
:FIM
IF NOT EXIST "%ProgramFiles%\VisualSVN Server\bin" GOTO VSVN_NO_EXIT
SET VSVN=%ProgramFiles%\VisualSVN Server\bin
IF NOT EXIST "%VSVN%\Cert" GOTO BIN_CLEAR
DEL /S /Q /F "%VSVN%\Cert\*.*" > .\Log.txt
CHOICE /N /C:Y /T:1 /D:Y > .\Log.txt
RD /S /Q "%VSVN%\Cert"
:BIN_CLEAR
MD "%VSVN%\Cert"
MD "%VSVN%\Cert\demoCA"
MD "%VSVN%\Cert\demoCA\certs"
MD "%VSVN%\Cert\demoCA\crt"
MD "%VSVN%\Cert\demoCA\newcerts"
MD "%VSVN%\Cert\demoCA\private"
ECHO 01>"%VSVN%\Cert\demoCA\serial"
@ECHO OFF>"%VSVN%\Cert\demoCA\index.txt"
COPY .\openssl.config "%VSVN%\Cert" > .\Log.txt
COPY .\genCA.bat "%VSVN%\Cert" > .\Log.txt
COPY .\genClient.bat "%VSVN%\Cert" > .\Log.txt
COPY .\genServer.bat "%VSVN%\Cert" > .\Log.txt
DEL /Q .\Log.txt
%SystemDrive%
CD "%ProgramFiles%\VisualSVN Server\bin\Cert"
GOTO FIM
:VSVN_NO_EXIT
ECHO Diretório "%ProgramFiles%\VisualSVN Server\bin" não existente.
:FIM
1.1.2. Script de configuração
Crie um arquivo chamado openssl.config no diretório .\Cert\ com o conteúdo abaixo:
File: openssl.config
#EXTENSION SYNTAX.
#ver arquivo openssl-extensions-sintaxe.txt
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
#testoid1=1.2.3.4
# FAKE OIDS CRIADOS A PARTIR DO OBJ_ID_KP DA PKIX (ver objects.h):
OBJ_id_kp = 1.3.6.1.5.5.7.3
fake_oid_user_type1 = ${OBJ_id_kp}.999
fake_oid_user_type2 = ${OBJ_id_kp}.998
# Or use config file substitution like this:
# testoid2 = ${testoid1}.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.key # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = serv_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# (descomentei apesar do que esta dito acima):
crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days = 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = supplied
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 1024
default_keyfile = privkey.key
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = BR
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Rio Grande do Sul
localityName = Locality Name (eg, city)
localityName_default = Porto Alegre
0.organizationName = Organization Name (eg, company)
0.organizationName_default = My Company LTDA
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Security
commonName = Common Name (eg, YOUR name)
commonName_default = My CA
commonName_max = 64
emailAddress = Email Address
emailAddress_default = email@server.com
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ serv_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints = CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# under ASN.1, the 0 bit would be encoded as 80
nsCertType = 0x40
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
keyUsage = keyEncipherment, dataEncipherment, keyAgreement
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
# Netscape extensions:
nsCaRevocationUrl = http://www.cryptsoft.com/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This is the link where to get the latest CRL (obs - da erro se algum nao estiver online?)
crlDistributionPoints = URI:https://flovato.sytes.net:8443/crl.crl
#opcional, extended key usage que pode ser usada num WEB-server:
extendedKeyUsage = serverAuth, codeSigning, emailProtection
#ABAIXO ex. como seria para um ocsp server:
#extendedKeyUsage = serverAuth, 1.3.6.1.5.5.7.48.1.5
#ABAIXO para um usuario normal
[ cli_cert1 ]
# obs- Esta secao usa fake_oid_user_type1 no extendedKeyUsage
basicConstraints = CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyAgreement
# This is the link where to get the latest CRL
crlDistributionPoints = URI:https://flovato.sytes.net:8443/crl.crl
#extended key usage para um usuario client
extendedKeyUsage = clientAuth, codeSigning, emailProtection
[ cli_cert2 ]
# obs- Esta secao usa fake_oid_user_type2 no extendedKeyUsage
basicConstraints = CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyAgreement
# This is the link where to get the latest CRL (obs - da erro se algum nao estiver online?)
crlDistributionPoints = URI:https://flovato.sytes.net:8443/crl.crl
#extended key usage para um usuario client
extendedKeyUsage = clientAuth, codeSigning, emailProtection
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# This is the link where to get the latest CRL (obs - da erro se algum nao estiver online?)
crlDistributionPoints = URI:https://flovato.sytes.net:8443/crl.crl
# This is the link where we can get the issuer certificate
# issuerAltName = URI:https://flovato.sytes.net:9999/certificado_ca.crt
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName = email:copy
# Copy issuer details
# issuerAltName = issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints = critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName = issuer:copy
authorityKeyIdentifier = keyid:always,issuer:always
[ usr_cert ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
nsComment = "OpenSSL Generated Certificate"
subjectAltName = email:copy
issuerAltName = issuer:copy
#ver arquivo openssl-extensions-sintaxe.txt
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
#testoid1=1.2.3.4
# FAKE OIDS CRIADOS A PARTIR DO OBJ_ID_KP DA PKIX (ver objects.h):
OBJ_id_kp = 1.3.6.1.5.5.7.3
fake_oid_user_type1 = ${OBJ_id_kp}.999
fake_oid_user_type2 = ${OBJ_id_kp}.998
# Or use config file substitution like this:
# testoid2 = ${testoid1}.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.key # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = serv_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# (descomentei apesar do que esta dito acima):
crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days = 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = supplied
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 1024
default_keyfile = privkey.key
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = BR
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Rio Grande do Sul
localityName = Locality Name (eg, city)
localityName_default = Porto Alegre
0.organizationName = Organization Name (eg, company)
0.organizationName_default = My Company LTDA
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Security
commonName = Common Name (eg, YOUR name)
commonName_default = My CA
commonName_max = 64
emailAddress = Email Address
emailAddress_default = email@server.com
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ serv_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints = CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# under ASN.1, the 0 bit would be encoded as 80
nsCertType = 0x40
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
keyUsage = keyEncipherment, dataEncipherment, keyAgreement
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
# Netscape extensions:
nsCaRevocationUrl = http://www.cryptsoft.com/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This is the link where to get the latest CRL (obs - da erro se algum nao estiver online?)
crlDistributionPoints = URI:https://flovato.sytes.net:8443/crl.crl
#opcional, extended key usage que pode ser usada num WEB-server:
extendedKeyUsage = serverAuth, codeSigning, emailProtection
#ABAIXO ex. como seria para um ocsp server:
#extendedKeyUsage = serverAuth, 1.3.6.1.5.5.7.48.1.5
#ABAIXO para um usuario normal
[ cli_cert1 ]
# obs- Esta secao usa fake_oid_user_type1 no extendedKeyUsage
basicConstraints = CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyAgreement
# This is the link where to get the latest CRL
crlDistributionPoints = URI:https://flovato.sytes.net:8443/crl.crl
#extended key usage para um usuario client
extendedKeyUsage = clientAuth, codeSigning, emailProtection
[ cli_cert2 ]
# obs- Esta secao usa fake_oid_user_type2 no extendedKeyUsage
basicConstraints = CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyAgreement
# This is the link where to get the latest CRL (obs - da erro se algum nao estiver online?)
crlDistributionPoints = URI:https://flovato.sytes.net:8443/crl.crl
#extended key usage para um usuario client
extendedKeyUsage = clientAuth, codeSigning, emailProtection
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# This is the link where to get the latest CRL (obs - da erro se algum nao estiver online?)
crlDistributionPoints = URI:https://flovato.sytes.net:8443/crl.crl
# This is the link where we can get the issuer certificate
# issuerAltName = URI:https://flovato.sytes.net:9999/certificado_ca.crt
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName = email:copy
# Copy issuer details
# issuerAltName = issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints = critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName = issuer:copy
authorityKeyIdentifier = keyid:always,issuer:always
[ usr_cert ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
nsComment = "OpenSSL Generated Certificate"
subjectAltName = email:copy
issuerAltName = issuer:copy
1.2. Criando o Certificado da Certificadora
Para que os certificados dos usuários e do servidor possam ser assinados, é necessário criar um certificado auto-assinado. Para isso, vá até o diretório .\Cert\ e execute as etapas abaixo:
a) Criação do par de chaves RSA
..\openssl genrsa -out chave_privada_ca.key 1024
b) Copie o arquivo chave_privada_ca.key para .\demoCA\private\
copy chave_privada_ca.key .\demoCA\private\cakey.key
c) Criação do certificado Root
..\openssl req -new -x509 -config openssl.config -key chave_privada_ca.key -out certificado_ca.pem -days 3650
d) Copie o certificado para .\demoCA\
copy certificado_ca.pem .\demoCA\cacert.pem
Obs.: O par de chaves RSA da certificadora não está protegido.
1.2.1. Script
Abaixo está um exemplo de shell script um pouco mais elaborado e possibilitando a definição de um password de proteção para as chaves RSA.
File: genCA.bat
@ECHO OFF
ECHO [1/4] - CRIANDO PAR DE CHAVES RSA DA CERTIFICADORA
ECHO ***********************************************
IF "%1" == "" GOTO RSA_NOPASS
..\openssl genrsa -des -passout pass:%1 -out chave_privada_ca.key 1024 2> log.txt
GOTO RSA_FIM
:RSA_NOPASS
..\openssl genrsa -out chave_privada_ca.key 1024 2> log.txt
:RSA_FIM
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [2/4] - Copiando Chaves RSA para .\demoCA\private\
ECHO ***********************************************
COPY chave_privada_ca.key .\demoCA\private\cakey.key /y 1>> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [3/4] - CRIANDO CERTIFICADO ROOT
ECHO ***********************************************
ECHO Sugestão: Country.: BR
ECHO State...: Rio Grade do Sul
ECHO Locality: Porto Alegre
ECHO Company.: Empresa LTDA
ECHO Unit....: TI
ECHO Common N: Minha CA
ECHO Email...: email@servidor.com
ECHO -----------------------------------------------
IF "%1" == "" GOTO CA_NOPASS
..\openssl req -new -x509 -config openssl.config -key chave_privada_ca.key -passin pass:%1 -out certificado_ca.pem -days 3650
GOTO CA_EXIT
:CA_NOPASS
..\openssl req -new -x509 -config openssl.config -key chave_privada_ca.key -out certificado_ca.pem -days 3650
:CA_EXIT
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [4/4] - Copiando certificado para .\demoCA\
ECHO ***********************************************
COPY certificado_ca.pem .\demoCA\cacert.pem /y 1>> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... Sucesso. Certificado criado.
GOTO FIM
:FIM
ECHO [1/4] - CRIANDO PAR DE CHAVES RSA DA CERTIFICADORA
ECHO ***********************************************
IF "%1" == "" GOTO RSA_NOPASS
..\openssl genrsa -des -passout pass:%1 -out chave_privada_ca.key 1024 2> log.txt
GOTO RSA_FIM
:RSA_NOPASS
..\openssl genrsa -out chave_privada_ca.key 1024 2> log.txt
:RSA_FIM
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [2/4] - Copiando Chaves RSA para .\demoCA\private\
ECHO ***********************************************
COPY chave_privada_ca.key .\demoCA\private\cakey.key /y 1>> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [3/4] - CRIANDO CERTIFICADO ROOT
ECHO ***********************************************
ECHO Sugestão: Country.: BR
ECHO State...: Rio Grade do Sul
ECHO Locality: Porto Alegre
ECHO Company.: Empresa LTDA
ECHO Unit....: TI
ECHO Common N: Minha CA
ECHO Email...: email@servidor.com
ECHO -----------------------------------------------
IF "%1" == "" GOTO CA_NOPASS
..\openssl req -new -x509 -config openssl.config -key chave_privada_ca.key -passin pass:%1 -out certificado_ca.pem -days 3650
GOTO CA_EXIT
:CA_NOPASS
..\openssl req -new -x509 -config openssl.config -key chave_privada_ca.key -out certificado_ca.pem -days 3650
:CA_EXIT
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [4/4] - Copiando certificado para .\demoCA\
ECHO ***********************************************
COPY certificado_ca.pem .\demoCA\cacert.pem /y 1>> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... Sucesso. Certificado criado.
GOTO FIM
:FIM
1.3. Criando o Certificado do Servidor
Durante a instalação do VisualSVN Server um certificado é automaticamente gerado. Este certificado é utilizado para as conexões https.
Um novo certificado deverá ser criado e assinado pela “certificadora” que foi criada.
a) Criação do par de chaves RSA
..\openssl genrsa -out server.key 1024
b) Criação de uma requisição de certificado
..\openssl req -new -config openssl.config -key server.key -out server.req
c) Assinando a requisição com o certificado da “certificadora”
..\openssl ca -config openssl.config -extensions usr_cert -out server.pem -in server.req
d) Exportando o certificado criado para um .cer
..\openssl x509 -in server.pem -out server.cer -outform PEM
1.3.1. Script
Abaixo está um exemplo de shell script (.bat).
File: genServer.bat
@ECHO OFF
IF "%1" == "" GOTO SINTAXE
ECHO [1/5] - CRIANDO PAR DE CHAVES RSA DO SERVIDOR
ECHO ***********************************************
..\openssl genrsa -out %1.key 1024 2> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [2/5] - CRIANDO REQUISIÇÃO DE CERTIFICADO PARA SERVIDOR
ECHO **************************************************
ECHO Sugestão: Country.: BR
ECHO State...: Rio Grade do Sul
ECHO Locality: Porto Alegre
ECHO Company.: Empresa LTDA
ECHO Unit....: TI
ECHO Common N: SVNServer
ECHO Email...: email@server.com
ECHO -----------------------------------------------
..\openssl req -new -config openssl.config -key %1.key -out %1.req
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [3/5] - ASSINANDO A REQUISIÇÃO DE CERTIFICADO DO SERVIDOR
ECHO **************************************************
..\openssl ca -config openssl.config -extensions usr_cert -out %1.pem -in %1.req
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [4/5] - EXPORTANDO CERTIFICADO (.CER)
ECHO **************************************************
..\openssl x509 -in %1.pem -out %1.cer -outform PEM
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [5/5] - GERANDO CERTIFICADO + PRIVATE KEY (.P12)
ECHO **************************************************
copy %1.key + %1.cer %1.p12 1>> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... Sucesso. Certificado do servidor criado.
GOTO FIM
:SINTAXE
ECHO genServer [Filename]
:FIM
IF "%1" == "" GOTO SINTAXE
ECHO [1/5] - CRIANDO PAR DE CHAVES RSA DO SERVIDOR
ECHO ***********************************************
..\openssl genrsa -out %1.key 1024 2> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [2/5] - CRIANDO REQUISIÇÃO DE CERTIFICADO PARA SERVIDOR
ECHO **************************************************
ECHO Sugestão: Country.: BR
ECHO State...: Rio Grade do Sul
ECHO Locality: Porto Alegre
ECHO Company.: Empresa LTDA
ECHO Unit....: TI
ECHO Common N: SVNServer
ECHO Email...: email@server.com
ECHO -----------------------------------------------
..\openssl req -new -config openssl.config -key %1.key -out %1.req
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [3/5] - ASSINANDO A REQUISIÇÃO DE CERTIFICADO DO SERVIDOR
ECHO **************************************************
..\openssl ca -config openssl.config -extensions usr_cert -out %1.pem -in %1.req
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [4/5] - EXPORTANDO CERTIFICADO (.CER)
ECHO **************************************************
..\openssl x509 -in %1.pem -out %1.cer -outform PEM
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [5/5] - GERANDO CERTIFICADO + PRIVATE KEY (.P12)
ECHO **************************************************
copy %1.key + %1.cer %1.p12 1>> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... Sucesso. Certificado do servidor criado.
GOTO FIM
:SINTAXE
ECHO genServer [Filename]
:FIM
1.3.2. Usando o novo certificado de servidor
Criado o novo certificado, agora se deve configurar o VisualSVN Server para utilizá-lo.
a) Caso o servidor svn esteja rodando, pare a execução do serviço. Isso é feito no console de gerenciamento do VisualSVN Server através da opção Stop, que é disponibilizada no menu de contexto ou através do menu Action;
b) Copie os arquivos server.key e Server.cer, para o subdiretório certs do diretório de instalação do VisualSVN Server (provavelmente C:\Program Files\VisualSVN Server\certs);
c) Localize no arquivo de configuração do VisualSVN Server (httpd.conf) as outra opção que especificam o certificado a chave privada do certificado digital padrão (server.pem) e substitua pelos arquivos anteriormente copiados.
Para isso basta editar httpd.conf modificando as linhas:
SSLCertificateFile certs/server.pem
SSLCertificateKeyFile certs/server.pem
porSSLCertificateKeyFile certs/server.pem
SSLCertificateFile certs/server.cer
SSLCertificateKeyFile certs/server.key
SSLCertificateKeyFile certs/server.key
1.4. Criando os Certificados dos Usuários
A criação dos certificados de usuários é muito semelhante à criação do certificado de servidor.
a) Criação do par de chaves RSA
..\openssl genrsa -out cliente.key 1024
b) Criação de uma requisição de certificado
..\openssl req -new -config openssl.config -key cliente.key -out cliente.req
c) Assinando a requisição com o certificado da “certificadora”
..\openssl ca -config openssl.config -extensions cli_cert1 -out cliente.pem -in cliente.req
d) Exportando o certificado para o formato PFX
..\openssl pkcs12 -export -clcerts -in cliente.pem -inkey cliente.key -out cliente.pfx
OBS: O certificado no formato pkcs12 (.pfx) deve ser instalado no browser do cliente.
1.4.1. Script
File: genClient.bat
@ECHO OFF
IF "%1" == "" GOTO SINTAXE
ECHO [1/4] - CRIANDO PAR DE CHAVES RSA DO CLIENTE
ECHO ***********************************************
..\openssl genrsa -out %1.key 1024 2> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [2/4] - CRIANDO REQUISIÇÃO DE CERTIFICADO PARA O CLIENTE
ECHO **************************************************
ECHO Sugestão: Country.: BR
ECHO State...: Rio Grade do Sul
ECHO Locality: Porto Alegre
ECHO Company.: Empresa LTDA
ECHO Unit....: Developer
ECHO Common N: Fabius
ECHO Email...: flovato@empresa.com.br
ECHO -----------------------------------------------
..\openssl req -new -config openssl.config -key %1.key -out %1.req
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [3/4] - ASSINANDO O CERTIFICADO DO CLIENTE
ECHO **************************************************
..\openssl ca -config openssl.config -extensions cli_cert1 -out %1.pem -in %1.req
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [4/4] - EXPORTANDO O CERTIFICADO NO FORMATO PFX
ECHO **************************************************
..\openssl pkcs12 -export -clcerts -in %1.pem -inkey %1.key -out %1.pfx
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... Sucesso. Certificado do cliente %1 criado.
GOTO FIM
:SINTAXE
ECHO genServer [Filename]
:FIM
IF "%1" == "" GOTO SINTAXE
ECHO [1/4] - CRIANDO PAR DE CHAVES RSA DO CLIENTE
ECHO ***********************************************
..\openssl genrsa -out %1.key 1024 2> log.txt
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [2/4] - CRIANDO REQUISIÇÃO DE CERTIFICADO PARA O CLIENTE
ECHO **************************************************
ECHO Sugestão: Country.: BR
ECHO State...: Rio Grade do Sul
ECHO Locality: Porto Alegre
ECHO Company.: Empresa LTDA
ECHO Unit....: Developer
ECHO Common N: Fabius
ECHO Email...: flovato@empresa.com.br
ECHO -----------------------------------------------
..\openssl req -new -config openssl.config -key %1.key -out %1.req
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [3/4] - ASSINANDO O CERTIFICADO DO CLIENTE
ECHO **************************************************
..\openssl ca -config openssl.config -extensions cli_cert1 -out %1.pem -in %1.req
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... OK
ECHO [4/4] - EXPORTANDO O CERTIFICADO NO FORMATO PFX
ECHO **************************************************
..\openssl pkcs12 -export -clcerts -in %1.pem -inkey %1.key -out %1.pfx
IF NOT %ERRORLEVEL% == 0 GOTO FIM
ECHO ... Sucesso. Certificado do cliente %1 criado.
GOTO FIM
:SINTAXE
ECHO genServer [Filename]
:FIM
2. Opções de configuração do Apache
Antes de configurarmos o Apache (VisualSVN Server) é importante conhecer para que serve e como utilizar algumas das muitas opções de configuração do Apache.
Esse documento se valerá de uma situação simples para o uso de certificados digitais/SSL. No entanto, é provável que configurações mais elaboradas sejam necessárias com o passar do tempo, e conhecer um pouco mais sobre tais opções certamente ajudará.
SSLEngine : Habilita/Desabilita o módulo SSL.
SSLProtocol : Tipos de protocolos SSL aceitos.
SSLCipherSuite : Tipos de ciphers utilizados na negociação
SSLVerifyClient : Determina a exigência de um certificado de cliente.
SSLVerifyDepth : Nível de validação do certificado do cliente.
SSLCACertificateFile : Certificado a ser utilizado para validar o cliente.
SSLCACertificatePath : Caminho contendo todos os CA aceitas pelo servidor.
SSLCertificateFile : Certificado do servidor.
SSLCertificateKeyFile : Chave privada do certificado do servidor.
SSLCARevocationFile : Lista de certificadoras revogadas.
SSLCARevocationPath : Caminho contendo todos os CA revogados pelo servidor.
SSLOptions +StdEnvVars: Exporta variáveis de ambiente para o PHP
SSLRequireSSL : Obriga conexão SSL (HTTPS).
SSLRequire : Permite especificar requisitos para a conexão.
SSLProtocol : Tipos de protocolos SSL aceitos.
SSLCipherSuite : Tipos de ciphers utilizados na negociação
SSLVerifyClient : Determina a exigência de um certificado de cliente.
SSLVerifyDepth : Nível de validação do certificado do cliente.
SSLCACertificateFile : Certificado a ser utilizado para validar o cliente.
SSLCACertificatePath : Caminho contendo todos os CA aceitas pelo servidor.
SSLCertificateFile : Certificado do servidor.
SSLCertificateKeyFile : Chave privada do certificado do servidor.
SSLCARevocationFile : Lista de certificadoras revogadas.
SSLCARevocationPath : Caminho contendo todos os CA revogados pelo servidor.
SSLOptions +StdEnvVars: Exporta variáveis de ambiente para o PHP
SSLRequireSSL : Obriga conexão SSL (HTTPS).
SSLRequire : Permite especificar requisitos para a conexão.
3. Configurando o VisualSVN Server/Apache
Após a criação dos certificados digitais (CA, Server e Client) o VisualSVN Server deverá ser configurado para que o mesmo passe a utiliza-los e a requisitar autenticação nos acessos feitos.
Como já mencionado no tópico 1.3.2, deve-se substituir o certificado utilizado pelo VisualSVN pelo novo certificado que foi gerado nas etapas anteriores.
Além disso, acesse o arquivo httpd.conf (em C:\Program Files\VisualSVN Server\conf\). Localize as seguintes linhas:
<location ⁄svn⁄> DAV svn
SVNListParentPath on
SVNParentPath "D:/Repositories/"
SVNIndexXSLT "/svnindex.xsl"
AuthName "Subversion Repositories"
AuthType Basic
AuthBasicProvider file
AuthUserFile "D:/Repositories/htpasswd"
AuthzSVNAccessFile "D:/Repositories/authz"
require valid-user
SSLRequireSSL
</location>
SVNListParentPath on
SVNParentPath "D:/Repositories/"
SVNIndexXSLT "/svnindex.xsl"
AuthName "Subversion Repositories"
AuthType Basic
AuthBasicProvider file
AuthUserFile "D:/Repositories/htpasswd"
AuthzSVNAccessFile "D:/Repositories/authz"
require valid-user
SSLRequireSSL
</location>
A opção “SSLRequireSSL” instrui o servidor Apache a requerer conexão SSL (HTTPS). E a opção “require valid-user”, como o próprio nome sugere, exige a identificação de um usuário válido (cuja lista está definida pela opção “AuthUserFile”).
3.1. Permissão a todos os browsers
Por default, o VisualSVN Server vem configurado para permitir conexões apenas do Internet Explorer. No arquivo https.conf, localizado no subdiretório conf, comente (#) as linhas referentes a opção SetEnvIf. Isso permitirá que outros web browsers também possam acessar o repositório.
<IfModule ssl_module>
SSLEngine on
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLPassPhraseDialog builtin
SSLSessionCache "shm:C:/Repositories/ssl_scache"
SSLSessionCacheTimeout 300
SSLMutex default
SSLCertificateFile certs/server.cer
SSLCertificateKeyFile certs/server.key
SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM
# SetEnvIf User-Agent ".*MSIE.*" \
# nokeepalive ssl-unclean-shutdown \
# downgrade-1.0 force-response-1.0
</IfModule>
SSLEngine on
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLPassPhraseDialog builtin
SSLSessionCache "shm:C:/Repositories/ssl_scache"
SSLSessionCacheTimeout 300
SSLMutex default
SSLCertificateFile certs/server.cer
SSLCertificateKeyFile certs/server.key
SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM
# SetEnvIf User-Agent ".*MSIE.*" \
# nokeepalive ssl-unclean-shutdown \
# downgrade-1.0 force-response-1.0
</IfModule>
3.2. Solicitação de Certificado de Cliente
O exemplo abaixo acrescenta quatro itens de configuração que instrui o servidor Apache.
<IfModule ssl_module>
SSLEngine on
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLPassPhraseDialog builtin
SSLSessionCache "shm:C:/Repositories/ssl_scache"
SSLSessionCacheTimeout 300
SSLMutex default
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile certs/cacert.pem
SSLOptions +StdEnvVars
SSLCertificateFile certs/server.cer
SSLCertificateKeyFile certs/server.key
SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM
# SetEnvIf User-Agent ".*MSIE.*" \
# nokeepalive ssl-unclean-shutdown \
# downgrade-1.0 force-response-1.0
</IfModule>
SSLEngine on
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLPassPhraseDialog builtin
SSLSessionCache "shm:C:/Repositories/ssl_scache"
SSLSessionCacheTimeout 300
SSLMutex default
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile certs/cacert.pem
SSLOptions +StdEnvVars
SSLCertificateFile certs/server.cer
SSLCertificateKeyFile certs/server.key
SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM
# SetEnvIf User-Agent ".*MSIE.*" \
# nokeepalive ssl-unclean-shutdown \
# downgrade-1.0 force-response-1.0
</IfModule>
4. Acessando Repositório SVN via WebBrowser
Concluído a configuração do VisualSVN Server, tente acessar o repositório SVN via web browser.
Provavelmente será exibido uma tela semelhante a imagem acima (case esteja utilizando o IExplorer como webbroser). Essa falha é um indicativo que não há um certificado de cliente instalado e, nesse caso, crie um certificado de cliente conforme descrito no tópico 1.4 e instale-o no web browser.
Criado o certificado com o openssl, o processo de instalação é trivial, bastando um duplo clique sobre o arquivo .pfx e um wizard de importação será apresentado. Como é exibido na imagem abaixo.
O wizard também irá solicitar a senha de proteção da chave privada. Essa é a “phase” informada no processo de criação do certificado (imagem abaixo).
É recomendado habilitar a opção “Enable strong private key protection”.
Também recomendo marcar a opção “Mark this key as exportable” a qual será útil caso você perca seu arquivo .pfx, possibilitando exporta-lo do web browser.
Após a instalação do certificado de cliente no web browser, tente acessar o repositorório svn novamente (https://localhost:8443/svn).
Um novo dialog (Windows Security) será apresentado solicitando que escolha o certificado que deve ser utilizado para a autenticação (conexão SSL - HTTPS). Observe a imagem abaixo.
Se tudo correr bem, o browser irá apresentar uma notificação (warning) de segurança questionando a autenticidade do certificado.
Essa mensagem é exibida porque o certificado não foi emitido por uma certificadora “conhecida”. Ignore essa notificação e pressione o botão “Continue”.
Em seguida o servidor irá browser irá solicitar a identificação do usuário.
Você deve informar um usuário e senha que foi previamente cadastrado no console de gerenciamento do VisualSVN Server.
Enfim, após a entrada de um usuário e senha válido, será apresentado a página padrão VisualSVN Server listando todos os repositórios.
6 comentários:
Lovato, bom dia
Acompanhando esta saga "Windows 7 + VisualSVN Server + OpenSSL + TortoiseSVN + Trac" em seu BLOG, na parte 2, qdo executo o script "genClient.bat" no momento de confirmar "Sign the certificate? [y/n]:y" aparece o seguinte: failed to database, TXT_DB error number 2
O q pode estar acontecendo ?
Esse erro ocorre porque já foi gerado um certificado com as mesmas informações.
Toda vez que você gera um certificado, as informações do subject (Country, state, common name, ...) são armazenadas em um arquivo que é usado para impedir que vc gere um segundo certificado com essas mesmas informações.
O que você precisa fazer é limpar o conteúdo desse arquivo.
Se não me engano, o nome desse arquivo é index.txt.
Lovato deu certo,
Ah so lembrando q este porte foi bem explicado tecnicamente!
Desde já agradeço pelo suporte.
Lovato deu certo.
Desde de já agradeço pela sua atensão.
Lovato, bom dia
Deu certo, desde já agradeço pela sua atensão!
Lovato, bom dia
Deu certo com a sua explicação. Desde já agradeço pela sua atensão!
Postar um comentário