ITK Programmer's Guide


 

Table of contents | Intro | General | TCP Low Level | TCP High Level | UDP | DNS | PPP
Encoding/Decoding | Internet Config | Goodies | Cryptography & SSL | Appendix

Chapter 11 : SSL and Cryptography routines

   

   

Chapter contents:

SSL support routines:

Cryptography routines:


About this chapter...

This chapter describes ITK's SSL related routines and general cryptography routines.


About ITK SSL support
Since version 2.5, ITK support SSL (Secured Socket Layer) version 2 and 3 as well as TLS (Transport Layer Secured) version 1. SSL support is only available in the "Pro" version of ITK and not available for 68K Macs .

This support is mostly transparent, all existing ITK v2 based code should work in SSL with almost no modification.

Here are the changes you need to do in order to use SSL instead of TCP:

Acting as a server :

Acting as a client :

All other ITK_TCP routines can be used on an SSL stream.

SSL Server Certificates and private keys

In order to act as a server, you must have a certificate that will allow the client to identify your server.

A certificate is a text file looking like this:

-----BEGIN CERTIFICATE-----
MIICqzCCAhSgAwIBAgIDKyXqMA0GCSqGSIb3DQEBBAUAMIGHMQswCQYDVQQGEwJa
QTEiMCAGA1UECBMZRk9SIFRFU1RJTkcgUFVSUE9TRVMgT05MWTEdMBsGA1UEChMU
...
jhsh9nP5wIYjia5GxuN4HWAJpnSFwC98LZcMqLU09+6XMymX8R2Voj0vBI8NlfQk
HgHQlPQulXcgaNONSP5A
-----END CERTIFICATE-----

A certificate is linked to a private key which is needed in order to use the certificate. The certificate is useless without the private key. The private key generated by ITK_MakeCSR (see below) is also a text file looking like this :

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDBO/ieW0VhcH/SniA6r9EPls6KBGWZDQVhzWLURXLe00VKgDOk
RrZ+L8umdlBZM1y1RPWaCM3U56WiOUfq/2wflnbtjgb14m7lbtr0e0UuKDZa7SJJ
...
Yvv+effpcMccy+amOxkCQGKGsjoMKhjgoifv1AElDWsFCK3OWiUFEWqWDYJcDVXK
RBQBN/B6lJof5D4GN1L3B4gHgcsxkSSqYj1ud34zppk=
-----END RSA PRIVATE KEY-----

A private key can be password protected, in that case, you'll need to provide the password in order to use the private key. A password protected private generate by ITK_MakeCSR key looks like this:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,D4A75236509E8F8C
   
Ii6hR/SwPlUgDUfy7bIk//Sc52zhL76ecvSKO4PBJ1rYpOYnHUrQF0YEvDuVuD8j
JdUGaC9i1bCKFU2Z3ryTXFUmU4rvWyXFs0Xq/sYb+o3kfwRo96VnpR7b1OsGom3K
...
y5WwsxBhUpKZOtgPjgGNCcIAf4dkBmzM50HrkSPW0klCRisZiuDyWYmMXL/dYDAh
7ez5I1K/GJSaAJyJxW7rzNpLa+V1gEEwDSXjoNNxXWJbmcuHRkf04A==
-----END RSA PRIVATE KEY-----
   

Generation of certificate signed requests (CSR) and private keys

Here is the process to generate a private key and obtain a certificate:

Use the small tool called "ITK_MakeCSR".

ITK_MakeCSR will first generate a private key, will ask you if you want to protect it using a password, then will ask for some informations that will be stored in your certificate:

ITK_MakeCSR creates two text files: a private key file (which can be password protected) named "keyout.pem", and a Certificate Signed Request (CSR) named "certreq.pem".

Once you have create your CSR, you can go thru one of the certification authorities (like Thawte , Verisign , Equifax, etc) to obtain your certificate. These certification authorities (CA) will ask you for your CSR and some ID papers to be sure that the certificate you are requesting match who you really are.

Then the CA will send you your certificate (also a text file).

If you just want to do some tests, you can obtain a test certificate instantly from Thawte (https://www.thawte.com/cgi/server/test.exe).

It is highly recommended to always do some tests with test certificates before buying a certificate from a certification authority. This will ensure that the certificate format is compatible with ITK.

Note about certificate and private key file format:

ITK uses certificates in PEM format.

These files are text files. Windows and MacOS are using differents kind of "end of lines" in text files. Windows standard is ending lines with CR+LF, while MacOS uses only a CR.

ITK v2.5 recognize CRLF end of lines under both MacOS and Windows, and also recognize CR under MacOs (but not under Windows).

Be sure to use the right kind of "end of line" in your certificate and private key files otherwise, these files will be unusable.

ITK_SSLSetCert

Not available in ITK Light or on 68K Macs

Syntax:

error := ITK_SSLSetCert (streamRef; pKeyPath; certPath; password)


Description:

ITK_SSLSetCert allows to specify a private key and a certificate for a given stream.


Note:

ITK_SSLSetCert must be used BEFORE the stream gets connected . It is recommended to call ITK_SSLSetCert just after calling ITK_TCPListen and before calling ITK_TCPStatus or ITK_TCPWaitConn.

Be sure to use FULL pathname for the private key and the cerficate files.


Starting with ITK v2.6, if streamRef is equal to 0, ITK_SSLSetCert will allow to set a default private key file, a default certificate file and a default password. This allows to be sure that a certificate is set BEFORE the stream gets connected. See the example...


Params:

In/Out

Parameter

Type

   

Example or note

->

streamRef

Longint

Stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

If left to 0, will set default private key, certificate and password (v2.6 and above)

->

pKeyPath

Text

Full Pathname of the private key

The private key file must be in PEM format.

->

certPath

Text

Full Pathname of the certificate

The certificate file must be in PEM format.

->

password

Text

Optional password for the private key

   

<-

error

Longint

Error code

0 = no error
-1 = invalid streamRef
-2 = not an SSL stream
-3 = invalid certificate
-4 = invalid private key of password


Example:

$streamRef := ITK_TCPListen(0;0;443) ` listen on HTTPS port
If ($streamRef # 0)
  ` set our server certificate immediately
  $err := ITK_SSLSetCert($streamRef;"myHD:myFolder:keyout.pem"; "myHD:myFolder:cert.pem";"")
  ...
         
Using default values machanism:
         
$err := ITK_SSLSetCert($streamRef;"myHD:myFolder:keyout.pem"; "myHD:myFolder:cert.pem";"") 
...
         
$streamRef := ITK_TCPListen(0;0;443) ` listen on HTTPS port
If ($streamRef # 0)
  ` no need to set the certificate infos, we can use the streamRef immediately
  $s := ITK_TCPWaitConn($s)
Back to top


ITK_SSLStrmInfo

Not available in ITK Light or on 68K Macs

Syntax:

error := ITK_SSLStrmInfo (streamRef;sslVers;cipher;keyBits;certData)


Description:

This routine allows to get some informations about the SSL stream like the version of SSL or TLS used, the cipher (encryption algorithm) used, and the length (in bits) of the key used to crypt the transmission as well as some data about the remote certificate (if you're acting as a client).

Since ITK v2.6.2, it can also be used to get the OpenSSL library version that is currently used by ITK (see example below).


Note:

This routine can only return valid informations when the stream is connected and SSL negociation has occured).


Params:

In/Out

Parameter

Type

   

Example or note

->

streamRef

Longint

Stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen.

Pass 0 to get the OpenSSL library version (ITK v2.6.2 and above).

<-

sslVers

Text

SSL version (as string)

Possible values:

  • "SSLv2"
  • "SSLv3"
  • "TLSv1"
<-

cipher

Text

Name of the cipher used

   

<-

keyLen

Longint

Length (in bits) of the cipher key

Common values:

  • 40 (export grade)
  • 56 (DES for example)
  • 128 (strong encryption)
  • 168 (TripleDES for example)
<-

certDate

Text

Certificate data

   

<-

error

Longint

Error code

0 = no error
-1 = invalid stream
-2 = not an SSL stream
-3 = the stream is not connected


Example:

$streamRef := ITK_TCPListen(0;0;443) ` listen on HTTPS port
If ($streamRef # 0)
  ` set our server certificate
  $err := ITK_SSLSetCert($streamRef;"myHD:myFolder:keyout.pem"; "myHD:myFolder:cert.pem";"")
  ` wait for connection
  $err := ITK_TCPWaitConn($streamRef)
  ` get some info about the connection
  $err := ITK_SSLStrmInfo($streamRef; $sslVers; $cipher; $keyLen)
  If ($keyLen >= 128)
    ` we are in "strong" 128bits (or above) mode
    ....

` Get the curent OpenSSL version with ITK v2.6.2 and above
$err := ITK_SSLStrmInfo(0;sslVers)
Back to top


ITK_SSLGetError

Not available in ITK Light or on 68K Macs

Syntax:

errNum := ITK_SSLGetError (streamRef;errString)


Description:

This routine allows to get details on the last error that occured on the given stream.

An error code is returned, as well as a error string which gives more details on the error.


Note:

The string returned as the following format:

  • error followed by the numeric error code in hexadecimal
  • the part of the SSL library where the error occured
  • the routine name where the error occured
  • a text explanation of the error

Example:

error:0906A068:PEM routines:PEM_do_header:bad password read

The error 0906A068 occured in the PEM Routines, more precisely in the PEM_do_header routine, and the problem was a "bad password read".


Params:

In/Out

Parameter

Type

   

Example or note

->

streamRef

Longint

Stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

<-

errString

Text

Error details

The error string contains:

  • the error code (error
<-

errNum

Longint

Error code

0 = no error
otherwise return an OpenSSL error code


Example:

$streamRef := ITK_TCPListen(0;0;443) ` listen on HTTPS port
If ($streamRef # 0)
  ` set our server certificate
  $err := ITK_SSLSetCert($streamRef;"myHD:myFolder:keyout.pem"; "myHD:myFolder:cert.pem";"")
  If ($err # 0)
    $err := ITK_SSLGetError($streamRef; $error)
    Alert("SSL "+$error)
    ...
Back to top


ITK_SSLSetCiphers

v2.6 and above, Not available in ITK Light or on 68K Macs

Syntax:

errNum := ITK_SSLSetCiphers (streamRef;cipherList)


Description:

This routine allows to select which ciphers will be accepted on the given SSL stream. The cipher list follows OpenSSL cipher list syntax.


Note:


Params:

In/Out

Parameter

Type

   

Example or note

->

streamRef

Longint

Stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

->

cipherList

Text

Cipher list definition

Leave blank to use default the cipher list.

<-

errNum

Longint

Error code

0 = no error
otherwise return an OpenSSL error code


Example:

$streamRef := ITK_TCPListen(0;0;443) ` listen on HTTPS port
If ($streamRef # 0)
  ` set our server certificate
  $err := ITK_SSLSetCiphers($streamRef;"")
  ...
Back to top


About ITK Digest Calculation routine
A digest is like some "super-checksum" calculated on some data. They can be used as digital signatures or to transfer encrypted information.The original information cannot be recovered from the digest.

For example, MD5 digests can be used to had a digital signature to emails to ensure that the message content has not been changed (see RFC#1544).

MD5 digests are also used in the POP3 APOP command which allows user authentication with transferring the user's password (see RFC#1939).

MD5 and SHA digests are also used in the SSL protocol.

RIPEMD-160 digests (added in ITK v2.0.4) are used by QuickDNS Pro load balancing system.

ITK 2.5 also supports SHA-1 (modified SHA) digests, as well as CRC32 and ADLER32 checksums.

Using ITK digest calculation routines

The first step is to initialise a digest calculation using ITK_DigestInit .
Then data are added to the calculation using the ITK_DigestAdd and ITK_DigestBlob routines
Finally, ITK_DigestCalc is called to get the final digest value (returned as a string).

ITK_DigestInit

Syntax:

digestRef := ITK_DigestInit (digestType)


Description:

ITK_DigestInit initialises a new digest calculation and returns a digest reference which will be needed in the next step of a digest calculation (ITK_DigestAdd or ITK_DigestBlob, then ITK_DigestCalc).


Params:

In/Out

Parameter

Type

   

Example or note

->

digestType

Longint

Digest type

1 = SHA digests (conforms to FIPS PUB 180)
2 = MD2 digests (conforms to RFC#1319)
4 = MD4 digests (conforms to RFC#1320, added in v2.5.1)
5 = MD5 digests (conforms to RFC#1321)
9 = SHA-1 digests (added in v2.5, conforms to FIPS PUB 180-1)
10 = RIPEMD160 digests (added in v2.0.4)
100 = CRC32 checksum (added in v2.5, conforms to ISO3309)
101 = ADLER32 checksum (added in v2.5)

<-

digestRef

Longint

Digest Reference

   


Example:

$digestRef := ITK_DigestInit(2) ` start MD2 digest calculation
ITK_DigestAdd($digestRef;"Here is some text")
ITK_DigestAdd($digestRef;"and some more")
ITK_DigestBlob($digestRef;myBlob)
$myDigest := ITK_DigestCalc($digestRef) ` get the result
Back to top


ITK_DigestAdd

Syntax:

ITK_DigestAdd (digestRef;text)


Description:

Adds some text to a current digest calculation referenced by digestRef.

This routine may be called several times during a digest calculation.


Params:

In/Out

Parameter

Type

   

Example or note

->

digestRef

Longint

Digest reference

As returned by ITK_DigestInit

->

text

Text

Text to add to the calculation

   


Example:

$digestRef := ITK_DigestInit(2) ` start MD2 digest calculation
         ITK_DigestAdd($digestRef;"Here is some text")
         ITK_DigestAdd($digestRef;"and some more")
ITK_DigestBlob($digestRef;myBlob)
$myDigest := ITK_DigestCalc($digestRef) ` get the result
Back to top


ITK_DigestBlob

Syntax:

ITK_DigestBlob (digestRef;blob)


Description:

Adds some data contained in a blob to a current digest calculation referenced by digestRef.

This routine may be called several times during a digest calculation.


Params:

In/Out

Parameter

Type

   

Example or note

->

digestRef

Longint

Digest reference

As returned by ITK_DigestInit

->

blob

Blob

Data to add to the calculation

   


Example:

$digestRef := ITK_DigestInit(2) ` start MD2 digest calculation
ITK_DigestAdd($digestRef;"Here is some text")
ITK_DigestAdd($digestRef;"and some more")
         ITK_DigestBlob($digestRef;myBlob)
$myDigest := ITK_DigestCalc($digestRef) ` get the result
Back to top


ITK_DigestCalc

Syntax:

digest := ITK_DigestCalc (digestRef;digestFormat)


Description:

Terminates the digest calculation and returns the calculated digest according to the format option.

After calling this routine, the digestRef previously returned by ITK_DigestInit is not valid anymore.


Params:

In/Out

Parameter

Type

   

Example or note

->

digestRef

Longint

Digest reference

As returned by ITK_DigestInit

->

digestFormat

Longint

Desired format for the digest result

0 = 8bit text
1 = lowercase hexadecimal encoded string

<-

digest

Text

Digest calculation result

   


Example:

$digestRef := ITK_DigestInit(2) ` start MD2 digest calculation
ITK_DigestAdd($digestRef;"Here is some text")
ITK_DigestAdd($digestRef;"and some more")
ITK_DigestBlob($digestRef;myBlob)
$myDigest := ITK_DigestCalc($digestRef) ` get the result
Back to top


ITK_Rot13Text

Syntax:

encodedText := ITK_Rot13Text (originalText)


Description:

Applies ROT13 "light encryption" to some text.

ROT13 is an email standard to hide some text. It is not a real encryption, only a shift in characters to make some text unreadable.

ROT13 is auto-reversible, apply it a second time to get the original text back.
So: ROT13(ROT13(text)) = text

If the original text was 7bit only, the resulting text will still be a 7bit only text.


Params:

In/Out

Parameter

Type

   

Example or note

->

originalText

Text

Original text

   

<-

encodedText

Text

Encoded text

   


Example:

$rot13 := ITK_Rot13Text("Hello")
Back to top


ITK_Rot13Blob

Syntax:

ITK_Rot13Blob (theBlob)


Description:

Applies ROT13 "light encryption" to a blob.

ROT13 is an email standard to hide some data. It is not a real encryption, only a shift in characters to make some data unreadable.

ROT13 is auto-reversible, apply it a second time to get the original data back.

If the original data was 7bit only, the resulting data will still be a 7bit only text.

The original blob is directly "encrypted" to avoid a copy in memory.


Params:

In/Out

Parameter

Type

   

Example or note

<->

theBlob

Blob

Original Blob

   


Example:

ITK_Rot13Blob(myBlob)
Back to top


ITK_Rot13Blob

Syntax:

ITK_Rot13Blob (theBlob)


Description:

Applies ROT13 "light encryption" to a blob.

ROT13 is an email standard to hide some data. It is not a real encryption, only a shift in characters to make some data unreadable.

ROT13 is auto-reversible, apply it a second time to get the original data back.

If the original data was 7bit only, the resulting data will still be a 7bit only text.

The original blob is directly "encrypted" to avoid a copy in memory.


Params:

In/Out

Parameter

Type

   

Example or note

<->

theBlob

Blob

Original Blob

   


Example:

ITK_Rot13Blob(myBlob)
Back to top


About encyption/decryption algorithms
ITK v2.5 supports several ciphers (encryption/decryption algorithms):

Algorithm name

Algorithm ID

Key length (bits)

DES

kCipherAlgDES (1)

56 (in fact 8 x 7bits chars)

TripleDES

kCipherAlgTripleDES (2)

168 (in fact 24 x 7bits chars)

3Way

kCipherAlgThreeWay (3)

96

CAST-128 (defined in RFC#2144)

kCipherAlgCAST_128 (8)

128

TwoFish-128

kCipherAlgTWOFISH_128 (10)

128

Unix Crypt

kCipherAlgUnixCrypt (28)

64, stream algorithm

These algorithms are working on block of data. There are several block mode supported by ITKv2.5 :

Block mode name

Block mode ID

CBC

kCiphermodeCBC (0)

ECB

kCiphermodeECB (1)

CFB

kCiphermodeCFB (2)

OFB

kCiphermodeOFB (3)

nOFB

kCiphermodenOFB (4)

stream

kCiphermodeStream (5)

It is mandatory to use the same algorithm and the same block mode while encrypting and decrypting.


ITK_EncryptText

Not available in ITK Light

Syntax:

error := ITK_EncryptText (text; secretKey; algoID; blockMode; IV)


Description:

ITK_EncryptText can be used to encrypt some text using your choice of cipher algorithm and block mode.

You will be able to decrypt it using ITK_DecryptText.


Params:

In/Out

Parameter

Type

   

Example or note

<->

text

Text

Clear text to encrypt

   

->

secretKey

Text

Key to encrypt the text

   

->

algoID

Longint

Type of algorithm to use

see above table

->

blockMode

Longint

Type of block mode to use

see above table

->

IV

Text

Initial Vectors

(ITK v2.6b1 and above)

<-

error

Longint

Error code

0 = no error
-1 = could not initialize cipher
-2 = unknown algorithm


Example:

err := ITK_EncryptText(text;"12345678";kCipherAlgDES;kCiphermodeECB)
Back to top


ITK_DecryptText

Not available in ITK Light

Syntax:

error := ITK_DecryptText (text; secretKey; algoID; blockMode; IV)


Description:

ITK_DecryptText can be used to decrypt some text using your choice of cipher algorithm and block mode.


Params:

In/Out

Parameter

Type

   

Example or note

<->

text

Text

Encrypted to decrypt

   

->

secretKey

Text

Key to decrypt the text

   

->

algoID

Longint

Type of algorithm to use

see above table

->

blockMode

Longint

Type of block mode to use

see above table

->

IV

Text

Initial Vectors

(ITK v2.6b1 and above)

<-

error

Longint

Error code

0 = no error
-1 = could not initialize cipher
-2 = unknown algorithm


Example:

err := ITK_DecryptText(text;"12345678";kCipherAlgDES;kCiphermodeECB)
         
Back to top


ITK_EncryptBlob

Not available in ITK Light

Syntax:

error := ITK_EncryptText (blob; secretKey; algoID; blockMode; IV)


Description:

ITK_EncryptBlob can be used to encrypt a blob content using your choice of cipher algorithm and block mode.

You will be able to decrypt it using ITK_DecryptBlob.


Params:

In/Out

Parameter

Type

   

Example or note

<->

blob

Blob

Blob to encrypt

   

->

secretKey

Text

Key to encrypt the text

   

->

algoID

Longint

Type of algorithm to use

see above table

->

blockMode

Longint

Type of block mode to use

see above table

->

IV

Text

Initial Vectors

(ITK v2.6b1 and above)

<-

error

Longint

Error code

0 = no error
-1 = could not initialize cipher
-2 = unknown algorithm


Example:

err := ITK_EncryptBlob(myBlob;"12345678";kCipherAlgDES;kCiphermodeECB)
Back to top


ITK_DecryptBlob

Not available in ITK Light

Syntax:

clearText := ITK_DecryptBlob (blob; secretKey; algoID; blockMode; IV)


Description:

ITK_DecryptBlob can be used to decrypt some text using you choice of cipher algorithm and block mode.


Params:

In/Out

Parameter

Type

   

Example or note

<->

blob

Blob

Blob to decrypt

   

->

secretKey

Text

Key to decrypt the text

   

->

algoID

Longint

Type of algorithm to use

see above table

->

blockMode

Longint

Type of block mode to use

see above table

->

IV

Text

Initial Vectors

(ITK v2.6b1 and above)

<-

error

Longint

Error code

0 = no error
-1 = could not initialize cipher
-2 = unknown algorithm


Example:

err := ITK_DecryptBlob (myBlob;"12345678";kCipherAlgDES;kCiphermodeECB)
Back to top


CQ/26-Nov-2004