Skip to content

pykiki/PyKI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PyKI

TLS Public Key Infrastructure manager

This is my first project, the goal was to have an easy to deploy and manage Public Key Infrastructure .

Please be easy with my code, I assume that all is not optimized, pythonic and as robust as I would like, but feel free to help to improve it.

And I apologize for my english too :p

Requirements and installation

Compatibilities

  • Python 3.X

Prerequisites

Install python modules dependencies

pip3 install cffi cryptography idna pyasn1 pycparser pyOpenSSL pytz six xkcdpass pycrypto setuptools

PyKI library installation

Create a virtual env, activate it and install the library.

To install it:

tar -xvzf PyKI-1.0.tar.gz
cd PyKI-1.0/
python3 setup.py install --record installation.log

To uninstall it:

pip uninstall PyKI

To be able to use it properly, you must create the PKI directory path with user file permissions:

sudo mkdir /opt/PyKI_data/
sudo -EH chown $USER /opt/PyKI_data/

PyKI filesystem

The PKI filesystem tree will be created as:

# First init when generating pki private key pair authentication #
>>
    /opt/PyKI_data/
    ├── CA
    ├── CERTS
    │   ├── clients
    │   └── servers
    ├── INTERMEDIATE
    └── passphrases
        └── public_key.pem
    6 directories, 1 files
>>
# Second init, when PKI is loaded successfully after authenticating #
>>
    /opt/PyKI_data/
    ├── CA
    │   ├── cacert.pem
    │   └── cakey.pem
    ├── CERTS
    │   ├── chain_cacert.pem
    │   ├── clients
    │   └── servers
    ├── INTERMEDIATE
    │   ├── crl.pem
    │   ├── intermediate_cacert.pem
    │   └── intermediate_cakey.pem
    ├── passphrases
    │   ├── pkipass.db
    │   └── public_key.pem
    └── pkicert.db
>>
    6 directories, 9 files

PKI usage

You can see examples for all funcs in "test/test-UseCase.py".

Quick start

pacman -S git python3 python-setuptools make gcc

git clone https://github.com/pykiki/PyKI.git cd PyKI/ python3 setup.py install --record installation.log cd

sudo -EH install -vd -o $USER -m 0750 /opt/PyKI_data/ cat > "/etc/pyki-config.ini" << EOF [DEFAULT] verbose : False

[pki auth] private key : ${HOME}/PyKI_authKey.pem key length : 8192 passphrase :

[pki params] c : FR st : BDR l : Calas o : $USER Corp. ou : IT Department email : ${USER}@gmail.com issuer : PyKI_${USER} private key size : 8192 certificate encryption : sha512 private key cipher : des3 crl encryption : sha256 EOF

init main pki key to keep private

pyki-gen_cert -n alain.maibach.fr -a DNS:alain.maibach.fr -p server --duration 360

choose your main password here and keep it secret.

remove server passphrase certificate

pyki-removePass -n alain.maibach.fr

${HOME}/PyKI_authKey.pem is to keep private

Servers cert:

#/opt/PyKI_data/CERTS/chain_cacert.pem #/opt/PyKI_data/CERTS/servers/alain.maibach.fr/alin.maibach.fr.crt #/opt/PyKI_data/CERTS/servers/alain.maibach.fr/alin.maibach.fr_unprotected.key

generate client certificate

pyki-gen_cert -n $USER -p client --duration 360 pyki-create_pkcs12 -n $USER -s yourpassword

/opt/PyKI_data/CERTS/clients/${USER/${USER}.p12


## Core module PyKIcore

> Load PyKI module:
>>```
#!/usr/bin/env python3
# -*- encoding: UTF-8 -*-
from PyKI import PyKIcore

### 1. PKI init'
>
1. _Initiate the PKI global default values_.
- _Construct (if needed) the PKI filesystem tree_.
- _Generate the PKI private key authentication (**First init' only**)_.
- _Authenticate PKI user (against it's private key)_.
- _Generate CA and intermediate certificates (**If they aren't already**)_.
- _Load CA and intermediate certificates_.
- _Check PKI integrity_.
> 
>**Parameters**:
>>* **verbose (boolean)**: Set verbosity.
* **issuerName (string)**: Set the ROOT certificates issuer names. You should use your organization name.
* **authKeypass (string)**: Set the pki private key passphrase in order to protect the pki calling.
* **privkeyStr (string)**: Must contain the pki private key file content.
* **authKeylen (int)**: Set PKI authentication private key size, must be in [1024, 2048, 4096, 8192].
* **C (string)**: Set default certificate Country name.
* **ST (string)**: Set default certificate State name.
* **L (string)**: Set default certificate Locality name.
* **O (string)**: Set default certificate Organization name.
* **OU (string)**: Set default certificate Organiational Unit name.
* **adminEmail (string)**: Set default certificate administrator e-mail @.
* **KEY_SIZE (int)**: Set default private key size, must be in [1024, 2048, 4096, 8192].
* **SIGN_ALGO (string)**: Set default certificate encryption (signature algorithm), must be in [SHA1, SHA256, SHA512].
* **KEY_CIPHER (string)**: Set default rsa private key cipher.

>>>>
- des (encrypt the generated key with DES in cbc mode)
- des3 (encrypt the generated key with DES in ede cbc mode (168 bit key)
- seed (encrypt PEM output with cbc seed)
- aes128, aes192, aes256 (encrypt PEM output with cbc aes)
- camellia128, camellia192, camellia256 (encrypt PEM output with cbc camellia)
>>
* **CRL_ALGO (string)**: Set CRL message digest, must be in ['MD2','MD5','MDC2','RMD160','SHA','SHA1','SHA224','SHA256','SHA384','SHA512'].
> 
>#### First PKI init' (_To do only once._)
>>- Define a passphrase for the private key which will be use to authenticate and will allow you to request the pki later.
>>
>>>```
    privateKeyPassphrase = 'apassphrasetokeep'
  • Define where to save the pki authentication key.
pkeyPath = "./pki_auth_cert.pem"
>>
>>- Init the pki with verbosity and some security custom params.
>>
>>>```
	pki = PyKIcore.PyKI(issuerName='PyKI_example', verbose = True, authKeypass=privateKeyPassphrase, authKeylen = 1024, KEY_SIZE = 1024, SIGN_ALGO = 'SHA1')
  • Save the pki authentication key.
# Retrieve authentication private key.
authprivkey = pki.initPkey	
# writing key to file.
try:
	wfile = open(pkeyPath, "wt")
except IOError:
	print('ERROR: unable to open file '+pkeyPath)
	exit(1)
else:
	try:
		wfile.write(authprivkey)
	except IOError:
		print('ERROR: Unable to write to file '+pkeyPath)
		exit(1)
	else:
		print('INFO: File ' + pkeyPath + ' written')
finally:
	wfile.close()
	authprivkey = None

>#### Usual PKI init' (_To call everytime you need to manage your PKI_)
>>- Get your pki authentication key into string format.
>>
>>>```
    pkey = open(pkeyPath ,'rt')
    pkeyStr = pkey.read()
    pkey.close()
  • Give the authentication key passphrase.
privateKeyPassphrase = 'apassphrasetokeep'
>>
>>- Init' the pki.
>> 
>>>```
	# With default values
		pki = PyKIcore.PyKI(authKeypass=privateKeyPassphrase, privkeyStr=pkeyStr)
>>>
	# Or with custom params
		pki = PyKIcore.PyKI(issuerName='PyKI_example', authKeypass=privateKeyPassphrase, authKeylen = 1024, KEY_SIZE = 1024, SIGN_ALGO = 'SHA1')

2. Verbosity

If you need/want to set verbose mode, you can do it these ways:

- Any time after having called PyKI class: pki.set_verbosity(True)

- During PyKI class calling: PyKIcore.PyKI(verbose = True, ...)

3. Callable vars

You will have to get them like this: pki.[name]

  • srvCRTdir : Get the directory path for server certificates
  • cltCRTdir : Get the directory path for client certificates
  • crtsDir : Get the directory path for the pki certificates
  • initPkey : Retrieve authentication private key (Usable only at first init)
  • pkidbDict : Get pki db as Dict
  • nameList : Retrieve list of certificates names

You will have to set them like this: pki.[name]='value'

  • pkeysize : Set private key size
  • crtenc : Set certificate encryption algorithm
  • keycipher : Set private key passphrase cipher encyption
  • crlenc : Set crl encryption algorithm

4. Generate a private key

This stage is mandatory because it will generate a private key to be able to generate a certificate later.

Parameters:

  • passphrase (str): Private key encryption passphrase. Can be leave as None to generate an unprotected key (not recommended).
  • keysize (int): Private key encryption length. Must be in [1024,2048,4096,8192].
  • name (str): Private key name which must match the certificate common name.
  • usage (str): Set the certificate usage type.
    Can be: serverAuth or clientAuth or None. Default: serverAuth.
  • ca (boolean): Indicate if the key will be use to generate a CA type certificate.

Return:

Informational result dict: {'error': Boolean, 'message': String}

Example:

# Init pki using 'Usual PKI init' (section 1) example and then
key = pki.create_key(passphrase='azerty', keysize=1024, name="www.ritano.fr", KeyPurpose="serverAuth")
if key['error'] :
	print(key['message'])
	print("ERROR: Unable to generate key "+name+" properly, aborting...")
	exit(1)
else:
	print(key['message'])
	print("INFO: Key "+name+" generated.")

### 5. Generate a TLS certificate
> Create a PEM X509 signed certificate.
>
**Parameters**:
>>* **country (_str_)**: Certificate country information.
* **state (_str_)**: Certificate state information.
* **city (_str_)**: Certificate city information.
* **org (_str_)**: Certificate organization information.
* **ou (_str_)**: Certificate organization unit information.
* **email (_str_)**: Certificate administrator e-mail information.
* **subjectAltName (_list of string_)**: Certificate Subject Alt-names extension. Must be in this format ___[ 'type:value' ]___ and types are '**email**', '**URI**', '**IP**', '**DNS**'.
* **cn (_str_)**: Certificate Common Name.
* **encryption (_str_)**: Certificate encryption (SHA1/SHA256/SHA512).
* **ca (_boolean_)**: Indicate if the key will be use to generate a CA type certificate.
* **valid\_before (_int_)**: Allow to generate a certificate which will be valid (from now) in number of days in the futur.
* **days\_valid (_int_)**: Set the periode, in days, during which the certfiicate will be valid. If valid_before is specified the validity will start at valid_before time .
* **KeyPurpose (_str_)**: Set the certificate usage purpose. Could be for server (serverAuth) or client authentication(clientAuth), if not specified, the certificate will support both.
* **KeyUsage (_str_)**: Define the certificate usage. Could be [digitalSignature, nonRepudiation, contentCommitment, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly], if not specified, the certificate will bear keyEncipherment and dataEncipherment.
* **ocspURI (_list of str_)**: Certificate authorityInfoAccess(OCSP) extension. Must be in this format [ 'val;type:value' ] where val can be (caIssuers|OCSP) and types are 'URI', 'IP' or 'DNS'.
* **CRLdp (_list of str_)**: Certificate crlDistributionPoints extension. Must be in this format [ 'type:value' ] and types are 'URI', 'IP' or 'DNS'.
* **toRenew (_Boolean._)**: Allow to specify that we want to renew the certificate without revoking but replacing the current one.
>
**Return**:
>>Informational result dict: _{'error': Boolean, 'message': String}_
>
**Example**:
>>```
	# Init pki using 'Usual PKI init' (section 1) example and then
	cert = pki.create_cert(
                       country = 'FR', state = 'PACA', city = 'Antibes',
                       org = 'Maibach.fr', ou = 'IT',
                       email = 'alain@maibach.fr',
                       KeyPurpose = 'serverAuth',
                       KeyUsage = 'keyEncipherment, dataEncipherment, digitalSignature',
                       subjectAltName = ['DNS:www.ritano.fr', 'DNS:wiki.maibach.fr', 'IP:10.0.0.1'],
                       cn = 'www.ritano.fr',
                       encryption = 'sha1',
                       days_valid = '180'
                      )
	if cert['error'] :
		print("ERROR: Unable to generate certificate "+name+" properly --> "+cert['message']+", aborting...")
		return(False)
	else:
		print(cert['message'])

    # create cert with ocsp and crl distribution point
	cert = pki.create_cert(
                       country = 'FR', state = 'PACA', city = 'Antibes',
                       org = 'Maibach.fr', ou = 'IT',
                       email = 'alain@maibach.fr',
                       KeyPurpose = 'serverAuth',
                       KeyUsage = 'keyEncipherment, dataEncipherment, digitalSignature',
                       subjectAltName = ['DNS:www.ritano.fr', 'DNS:wiki.maibach.fr', 'IP:10.0.0.1'],
                       cn = 'www.ritano.fr',
                       encryption = 'sha1',
                       days_valid = '180',
                       CRLdp='URI:https://wiki.maibach.fr/cacert.pem',
                       ocspURI='OCSP;URI:https://wiki.maibach.fr caIssuers;URI:https://wiki.maibach.fr/cacert.pem'
                      )

6. Remove passphrase

Removing passphrase from certificate.

Parameters:

  • keyname (str): PKI certificate name associated to the private key.
  • privKeypass (str): Private key passphrase.

Return:

Informational result dict: {'error': Boolean, 'message': String}

Example:

# Init pki using 'Usual PKI init' (section 1) example and then
pki.unprotect_key(keyname = 'www.ritano.fr', privKeypass = 'azerty')
if unprotectres['error']:
	print(unprotectres['message'])
	return(False)
print(unprotectres['message'])

### 7. Get certificate informations
> Get all certificate informations and added extensions.
>
**Parameters**:
>>* **certname (_str_)**: certificate name in the PKI.
>
**Return**:
>>Informational result dict _{'error': Boolean, 'message': Formatted string containing all certificate text infos}_
>
**Example**:
>>```
	# Init pki using 'Usual PKI init' (section 1) example and then
	cert_info = pki.get_certinfo('www.ritano.fr')
	if cert_info['error']:
		print(cert_info['message'])
	else:
		print("\n"+cert_info['message'])

8. Check certificate validity

Check if the certificate is still valid (not revoked and not expired).

Parameters:

  • cert (str): Certificate file path to check.

Return:

Informational result dict: {'error': Boolean, 'message': String}

Example:

# Init pki using 'Usual PKI init' (section 1) example and then
name = 'www.ritano.fr'
valid = pki.chk_validity(name)
if valid['error']:
	print(valid['message'])
else:
	print("Success "+valid['message'])

### 9. Check certificate conformity
> Check if the certificate has been generated by the current PKI.
>
**Parameters**:
>>* **cert (_str_)**: Certificate file path to check.
>
**Return**:
>>Informational result dict: _{'error': Boolean, 'message': String}_
>
**Example**:
>>```
	# Init pki using 'Usual PKI init' (section 1) example and then
	conform = pki.chk_conformity(cert="/opt/PyKI_data/CERTS/servers/www.ritano.fr/www.ritano.fr.crt")
	if conform['error']:
		print(conform['message'])
	else:
		print("Success "+conform['message'])

10. Check private key vs. certificate

Check that your private key match the certificate.

Parameters:

  • cert (str): Certificate file path.
  • key (str): Private key file path.
  • keypass (str): Private key passphrase if needed.

Return:

Informational result dict: {'error': Boolean, 'message': String}

Example:

# Init pki using 'Usual PKI init' (section 1) example and then
passphrase = 'azerty'
# if you do not specify it, and the key is encrypted, you will be prompted for it
#passphrase = None
reschk = pki.check_cer_vs_key(
	cert="/opt/PyKI_data/CERTS/signed/test_gencsr/test_gencsr.crt",
	key="/opt/PyKI_data/CERTS/requests/test_gencsr/test_gencsr.key",
	keypass = passphrase
)
if reschk['error']:
	print(reschk['message'])
elif mainVerbosity:
	print(reschk['message'])

### 11. Create a PKCS12 file
> Create a PKCS12 file for the PKI certificate name specified.
>
**Parameters**:
>>* **pkcs12name (_str_)**: PKI existing certificate name.
* **pkcs12pwd (_str_)**: PKCS12 file password.
>
**Return**:
>>Informational result dict: _{'error': Boolean, 'message': String}_
>
**Example**:
>>```
	# Init pki using 'Usual PKI init' (section 1) example and then
	clientpkcs12 = pki.create_pkcs12(pkcs12pwd='azerty', pkcs12name='www.ritano.fr')
    if clientpkcs12['error']:
        print(clientpkcs12['message'])
    else:
        print("Success "+clientpkcs12['message'])

12. Extract a PKCS12 file

Try to extract ca, certificate and private key from a PKCS12 file, to a specified destination.

Parameters:

  • pkcs12file (str): PKCS12 file path to extract.
  • pkcs12pwd (str): PKCS12 file password.
  • destdir (str): Extracted files destination directory.
  • inPrivKeypass (str): private key passphrase if the key is protected.

Return:

Informational result dict: {'error': Boolean, 'message': String}

Example:

# Init pki using 'Usual PKI init' (section 1) example and then
extractres = pki.extract_pkcs12(
 								pkcs12file='/opt/PyKI_data/CERTS/servers/www.ritano.fr/www.ritano.fr.p12',
 								pkcs12pwd='azerty',
 								destdir=pkcsfile+'_extracted/'
 							   )
if extractres['error']:
	print(extractres['message'])
elif mainVerbosity:
	print(extractres['message'])

### 13. Revoke a certificate
> Revoke a certificate with a revoking reason, remove all related files and regenerate the PKI crl.
>
**Parameters**:
>>* **certname (_str_)**: Certificaten name in PKI.
* **next\_crl\_days (_int_)**: Number of days to add for CRL expiry due to the CRL update.
* **reason (_bytes_)**: Certificate revocation reason to set in the CRL.  
Must be in [ ***unspecified, keyCompromise, CACompromise, affiliationChanged,superseded, cessationOfOperation, certificateHold*** ] .
* **date (_str_)**: Date to reach for considering the certificate as revoked (Format: "%d/%m/%Y"). If not specified, the revocation comes immediately.
* **renewal (_bool_)**: Specify if the revocation is called for a certificate renewal process.
>
**Return**:
>>Informational result dict: _{'error': Boolean, 'message': String}_
>
**Example**:
>>```
	# Init pki using 'Usual PKI init' (section 1) example and then
	crl = pki.revoke_cert(certname='www.ritano.fr', reason = "cessationOfOperation")
	if crl['error']:
		print(crl['message'])
	else:
		print("Success "+crl['message'])

14. Generate CSR

Generate a private key and it's Certificate Signing Request.

Parameters:

  • passphrase (str): Private key passphrase.
  • country (str): Certificate country information.
  • subjectAltName (list of string): Certificate Subject Alt-names extension. Must be in this format [ 'type:value' ] and types are 'email', 'URI', 'IP', 'DNS'.
  • state (str): Certificate state information.
  • city (str): Certificate city information.
  • org (str): Certificate organization information.
  • ou (str): Certificate organization unit information.
  • cn (str): Certificate Common Name.
  • email (str): Certificate administrator e-mail information.
  • encryption (str): Private key encryption (SHA1/SHA256/SHA512).
  • keysize (int): Private key size must be in [1024-8192].

Return:

Informational result dict: {'error': Boolean, 'message': String}

Example:

# Init pki using 'Usual PKI init' _(section 1)_ example and then
# create with a private key size of 1024.
csr = pki.create_csr(
                 	 passphrase = 'azerty',
                 	 country = 'BE', state = 'Antwerp', city = 'Mechelen',
                 	 org = 'In Serf we trust, Inc.', ou = 'Test Suite Server',
                 	 email = 'serfclient@example.com',
                 	 cn = 'test_gencsr',
                 	 encryption = 'SHA1',
                 	 keysize = 1024,
                 	 subjectAltName = ['DNS:test_gencsr', 'IP:10.0.0.1']
                	)
if csr['error']:
	print(csr['message'])
else:
	print('Success '+csr['message'])

### 15. Print Certificate Signing Request informations
> Print all Certificate Signing Request informations matching PKI name csr (_work only for csr generated by the pki_).
>
**Parameters**:
>>* **filepath (_str_)**: CSR file path.
>
**Return**:
>>Informational result dict _{ 'error': Boolean, 'message': Formatted string containing all csr text infos }_
>
**Example**:
>>```
	# Init pki using 'Usual PKI init' (section 1) example and then
	csr_info = pki.get_csrinfo('./test_gencsr.csr')
	if csr_info['error']:
		print(csr_info['message'])
	else:
		print("Success\n"+csr_info['message'])

16. Sign Certificate Signing Request

Signing a CSR file with a defined validity duration and add it to the PKI.

Parameters:

  • csr (str): Certificate Signing Request file path.
  • encryption (str): Certificate encryption (SHA1/SHA256/SHA512).
  • valid_before (int): Allow to generate a certificate which will be valid (from current time) in number of days in the future.
  • days_valid (int): Set the periode, in days, during which the certfiicate will be valid. If valid_before is specified the validity will start at valid_before time .
  • KeyPurpose (str): Set the certificate usage purpose. Could be for server (serverAuth) or client authentication(clientAuth), if not specified, the certificate will support both.
  • KeyUsage (str): Define the certificate usage. Could be [digitalSignature, nonRepudiation, contentCommitment, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly], if not specified, the certificate will bear keyEncipherment and dataEncipherment.

Return:

Informational result dict: {'error': Boolean, 'message': String}

Example:

# Init pki using 'Usual PKI init' (section 1) example and then
# Signing Certificate Request for 90 days of validity
signRes = pki.sign_csr(
	csr="/opt/PyKI_data/CERTS/requests/test_gencsr/test_gencsr.csr",
	KeyPurpose = "clientAuth",
	days_valid = 90,
	encryption = "SHA1"
)
if signRes['error'] :
	print("ERROR: Unable to generate certificate for csr "+csrpath+" properly --> "+signRes['message']+", aborting...")
elif mainVerbosity:
	print(signRes['message'])

### 17. Extend CRL duration
> Updating CRL expiry to X days from current time (same as if we would renew it before it expires).
>
**Parameters**:
>>* **next\_crl\_days (_int_)**: Number of days to add for CRL expiry.
>
**Return**:
>>Informational result dict: _{'error': Boolean, 'message': String}_
>
**Example**:
>>```
	# Init pki using 'Usual PKI init' (section 1) example and then
	# Updating crl expiry to 360 days
    renew = pki.renew_crl_date(next_crl_days = 360)
    if renew['error']:
        print(renew['message'])
    else:
        print('Success '+renew['message'])

18. PKI certificates database

This will allow you to consult PKI certificates database easyly. Mainly to get informations against certificates status.

Parameters:

None

Return:

Informational result dict: {'error': Boolean, 'message': String}

Example:

# Init pki using 'Usual PKI init' (section 1) example and then
# Get pki database info into list
pkidb = pki.pkidbDict
# for sorting names before printing datas
certsname = []
for certname in pkidb:
    certsname.append(certname)
# sort list insensitively
certsname.sort(key=lambda x: x.lower())
# process name list to print datas
for name in certsname:
    status = pkidb[name]['state']
    serial = pkidb[name]['serial']
    validity_time = pkidb[name]['duration']
    cert_shasum = pkidb[name]['shasum']
    cert_usage = pkidb[name]['type']
    cert_encrytion = pkidb[name]['shaenc']
    creation_date = pkidb[name]['created']
    print(
          'Certificate name: ' +name+ '\n',
          '\tCertificate state: ' +status+ '\n',
          '\tCertificate serial number: ', serial, '\n',
          '\tCertificate creation date: ' +creation_date+ '\n',
          '\tDays of validity after creation: ', validity_time, '\n',
          '\tCertificate sha sum: ' +cert_shasum+ '\n',
          '\tCertificate usage type: ' +cert_usage+ '\n',
          '\tCertificate encrytpion level: ' +cert_encrytion
    )

### 19. List certificates name
> List all certificates names, except for revoked, present in the PKI database.
>
**Parameters**:
>>None
>
**Return**:
>>Informational result dict: _{'error': Boolean, 'message': String}_
>
**Example**:
>>```
	# Init pki using 'Usual PKI init' (section 1) example and then
	print("List of PKI certificate names:")
	for name in pki.nameList:
		print("\t" + str(name))

20. Retrieve certificates passphrases

All certificates passphrases are stored securely (encrypted with AES). This module will allow you to get them. These are only readable if the PKI is correctly instanciated (the init authentication must be successfull).

Parameters:

None

Return:

Informational result dict: {'error': Boolean, 'message': String}

Example:

# Init pki using 'Usual PKI init' (section 1) example and then
# Retrieve certificates passphrases into list
passphrases = pki.loadpassDB()
if not passphrases['error']:
	print("\nList of passphrases stored:")
	for passphrase in passphrases['message']:
		print( 'Certificate Name: '+passphrase+' / passphrase: '+ passphrases['message'][passphrase] )
# Cleaning passphrases list to avoid keeping it in memory
passphrases.clear()

## Tips

### Global informations
> All functions return dict with 2 items: {'error': Boolean, 'message': String}.

### Certificates format
> The PKI creates RSA certificates in PEM format.

### Class init'
> We can redefine static params, concerning encryption, in the class init to enforce certificate security.  
For example we can manage the cryptographic algo setup with **self.\_\_KEY\_ALGO = crypto.TYPE\_RSA** .

### PKI lock file
> A lock is filed, during the class calling, into /opt/PyKI/pki.lock to avoid a concurrent usage.  
> While this lock is present, the PKI will be unusable by other.  

> A walkout mode can be set, based on this behavior.

### PKCS warnings
> - Be carefull when creating a PKCS file, the private key in it will be unprotected.  
> - Remember that the PKCS file is password protected.

### Certificates database
> Pkicert.db contains hashes whith an encryption Setd by HASH\_ENC.  
> By default it is hashed in ***'SHA1'***.  
> The PKI certificate names list can be retrieve by reading PyKI class var: 'nameList' (_see Section 19 of PKI usage_).

### PKI Passphrases database
> The store file '**pkipass.db**' contains encrypted passphrases of all private key for all certificates and certificate requests, generated by this pki.  
>
_Not any passwords for private keys are mandatory but strongly recommended ._

### Updating CA or Intermediate certificate
> If the CA root or intermedaire are expired, you'll just have to suppress the related certificate and init again the pki.
The certificate is generated from the existing private key (_which you **MUST** keep safely_).  
>
___Warning___:
>
>- During the pki init, take care of using same infos as previously used (City, Organisation, CN and so...).
> 
_During the init, the CA certificates are checked and generated._

### Testing your installation
> _Everything must run with no errors._
> 

#!/usr/bin/env bash

Used to test all PKI funcs

./test/test-UseCase.py

./test/test-gen_cert.py ./test/test-removePass.py ./test/test-create_pkcs12.py ./test/test-extract_pkcs12.py ./test/test-revoke_cert.py

./test/test-gen_csr.py ./test/test-sign_csr.py ./test/test-is_conform.py ./test/test-check_key_vs_cert.py

./test/test-get_infocert.py ./test/test-get_inforeq.py ./test/test-get_validity.py

./test/test-renew_crl.py ./test/test-get_passphrases.py ./test/test-read_pki_db.py

rm -r /opt/PyKI_data/

Usefull links

About

TLS Public Key Infrastructure manager

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages