SmartCardKerberos

From DcSharedWiki
Revision as of 20:17, 1 May 2010 by Pilou (talk | contribs) (add typographical conventions)

How to use smart card with Kerberos.

Requirements

  1. Software: Here programs that will be used. In parenthesises I have mentionned versions I have used.
    • openssl (0.9.8)
    • Kerberos server with pkinit plugin (MIT 1.6)
    • opensc (0.11.13)
    • pcscd (1.5.5)
  2. Hardware
    • a smart card: Feitian PKI card bought on http://www.gooze.eu/ There is a lot of documentation on this website.
    • smart card reader (mine is

External links

Typographical conventions

  • in commands listed below, you must replace `XX` by value depending of your configuration.
  • Constant width is used for `keywords`

Initialize smart card

An empty smart card can be initialized with:

# pin & puk will be asked
pkcs15-init --create-pkcs15 --profile pkcs15+onepin --use-default-transport-key --label "Pilou" 


A not empty smart card can be erased and initialized with:

pkcs15-init -E --label "Pilou"


Create a PKI

Private keys of root CA, server CA and clients CA will be stored on a smart card.

PKI structure

  • root CA: sign servers CA and clients CA
  • servers CA: sign servers certificates
    • kdc certificate
  • clients CA: sign clients certificates
    • user certificate

Create root CA

Root CA is a self-signed certificate. In order to create the certificate you need to generate a RSA key. This key can be either:

  • generated on the smart card
  • generated on a computer and copied on the smart card

RSA generated on the smart card

# (pin will be asked)
pkcs15-init --generate-key rsa/2048 --auth-id XX


Value of "--auth-id" parameter can be retreived with:

pkcs15-tool --list-pins


RSA generated on a computer and copied

openssl genrsa 2048 > id_rsa.pem
openssl rsa -pubout < id_rsa.pem > id_rsa.pub
pkcs15-init --store-private-key id_rsa.pem --auth-id XX # PIN will be asked or '--pin' can be used


create certificate

openssl req -config openssl.cnf -engine pkcs11 -key slot_XX-id_XX -keyform engine -extensions CA_ROOT -new -x509 -out ca.pem -text


`id` is same as value of parameter `--auth-id` and `slot` is indicated by:

pkcs11-tool --list-slots


openssl configuration

Here is my complete openssl.cnf file:


# This definition stops the following lines choking if HOME isn't
# defined.
HOME            = .
RANDFILE        = $ENV::HOME/.rnd

openssl_conf = openssl_init

[openssl_init]
engines     = engine_section
oid_section = new_oids

[ new_oids ]
pkkdcekuoid=1.3.6.1.5.2.3.5

[ ca ]
default_ca = CA_root_default

####################################################################
[ CA_root_default ]
dir              = ./ca
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
crlnumber        = $dir/crlnumber         # the current crl number
crl              = $dir/crl.pem           # The current CRL
#private_key     = $dir/private/cakey.pem # The private key
RANDFILE         = $dir/private/.rand     # private random number file
# 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
default_days     = 365                    # how long to certify for
default_crl_days = 30                     # how long before next CRL
default_md       = sha1                   # which md to use.
preserve         = no                     # keep passed DN ordering
policy           = policy_match

[ CA_serveur_default ]
dir              = ./cassl
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/cassl.pem         # The CA certificate
serial           = $dir/serial            # The current serial number
crlnumber        = $dir/crlnumber         # the current crl number
crl              = $dir/crl.pem           # The current CRL
#private_key     = $dir/private/cakey.pem # The private key
RANDFILE         = $dir/private/.rand     # private random number file
# 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
default_days     = 365                    # how long to certify for
default_crl_days = 30                     # how long before next CRL
default_md       = sha1                   # which md to use.
preserve         = no                     # keep passed DN ordering
policy           = policy_match

[ CA_client_default ]
dir              = ./client
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/client.pem        # The CA certificate
serial           = $dir/serial            # The current serial number
crlnumber        = $dir/crlnumber         # the current crl number
crl              = $dir/crl.pem           # The current CRL
#private_key     = $dir/private/cakey.pem # The private key
RANDFILE         = $dir/private/.rand     # private random number file
# 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
default_days     = 365               # how long to certify for
default_crl_days = 30                # how long before next CRL
default_md       = sha1              # which md to use.
preserve         = no                # keep passed DN ordering
policy           = policy_user

[ policy_match ]
countryName            = match
stateOrProvinceName    = match
organizationName       = match
organizationalUnitName = optional
commonName             = supplied
emailAddress           = optional

[ policy_user ]
countryName            = match
stateOrProvinceName    = match
organizationName       = match
organizationalUnitName = optional
commonName             = supplied
emailAddress           = supplied


####################################################################
[ req ]
default_bits           = 1024
default_keyfile        = privkey.pem
distinguished_name     = req_distinguished_name

# 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_distinguished_name ]
countryName                 = Country Name (2 letter code)
countryName_default         = FR
countryName_min             = 2
countryName_max             = 2
stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = Ile de France
localityName                = Locality Name (eg, city)
localityName_default        = Paris
0.organizationName          = Organization Name (eg, company)
0.organizationName_default  = PilouCorp
organizationalUnitName      = Organizational Unit Name (eg, section)
commonName                  = Common Name (eg, YOUR name)
commonName_max              = 64
emailAddress                = Email Address
emailAddress_max            = 64

[engine_section]
pkcs11 = pkcs11_section

[pkcs11_section]
engine_id = pkcs11
dynamic_path = /usr/lib/engines/engine_pkcs11.so
MODULE_PATH = /usr/lib/opensc-pkcs11.so
init = 0

[CA_ROOT]
nsComment                       = "CA Racine"
subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
basicConstraints                = critical,CA:TRUE,pathlen:1
keyUsage                        = keyCertSign, cRLSign

[CA_SERVEUR_SSL]
nsComment                       = "CA serveur SSL"
basicConstraints                = critical,CA:TRUE,pathlen:0
subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
issuerAltName                   = issuer:copy
keyUsage                        = keyCertSign, cRLSign
nsCertType                      = sslCA

[SERVEUR_SSL]
nsComment                       = "Certificat Serveur SSL"
subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
issuerAltName                   = issuer:copy
basicConstraints                = critical,CA:FALSE
keyUsage                        = digitalSignature, nonRepudiation, keyEncipherment
nsCertType                      = server
extendedKeyUsage                = serverAuth

[CA_CLIENT_SSL]
nsComment                       = "CA client SSL"
basicConstraints                = critical,CA:TRUE,pathlen:0
subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
issuerAltName                   = issuer:copy
keyUsage                        = keyCertSign, cRLSign
nsCertType                      = sslCA

[CLIENT_SSL]
nsComment                       = "Certificat Client SSL"
subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
issuerAltName                   = issuer:copy
basicConstraints                = critical,CA:FALSE
keyUsage                        = digitalSignature, nonRepudiation
nsCertType                      = client

[ KDC_CERT ]
nsComment                       = "KDC SERVEUR SSL"
subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
issuerAltName                   = issuer:copy
keyUsage                        = nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage                = pkkdcekuoid
basicConstraints                = critical,CA:FALSE
# Add id-pkinit-san (pkinit subjectAlternativeName)
subjectAltName                  = otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name

[kdc_princ_name]
realm          = EXP:0,GeneralString:${ENV::REALM}
principal_name = EXP:1,SEQUENCE:kdc_principal_seq

[kdc_principal_seq]
name_type   = EXP:0,INTEGER:1
name_string = EXP:1,SEQUENCE:kdc_principals

[kdc_principals]
princ1 = GeneralString:krbtgt
princ2 = GeneralString:${ENV::REALM}

[ CLIENT_CERT ]
nsComment                       = "KRB CLIENT SSL"
subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
issuerAltName                   = issuer:copy
keyUsage                        = digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage                = 1.3.6.1.5.2.3.4
basicConstraints                = CA:FALSE
subjectAltName                  = otherName:1.3.6.1.5.2.2;SEQUENCE:princ_name

[princ_name]
realm          = EXP:0, GeneralString:${ENV::REALM}
principal_name = EXP:1, SEQUENCE:principal_seq

[principal_seq]
name_type   = EXP:0, INTEGER:1
name_string = EXP:1, SEQUENCE:principals

[principals]
princ1 = GeneralString:${ENV::CLIENT}