print Print
Logo: Stiftung Secure Information and Communication Technologies SIC Stiftung Secure Information and Communication Technologies SIC

SecurityProvider Model

IAIK-CMS adopts the SecurityProvider model introduced by the IAIK-TLS library (iSaSiLk) for centralizing all cryptographic tasks into one class, iaik.cms.SecurityProvider.The SecurityProvider model used here is similar to that of iSaSiLk except for a the following changes:

  • Because of the high dependence of CMS onto ASN.1, IAIK-CMS makes use of the ASN.1 library of the crypto toolkit IAIK-JCE; so it cannot be used without having IAIK-JCE in the classpath (which does not necessarily mean to have to use (all the) the cryptographic engines provided by IAIK-JCE; i.e. any cryptographic task may be performed by any proper cryptography provider supporting the required engine).
  • Since CMS certificate handling requires access to certificate properties not supported by the JCA certificate API, any X.509 public key certficate used for IAIK-CMS has to be supplied as iaik.x509.X509Certficate, and any attribute certificate has to be supplied as iaik.x509.attr.AttributeCertificate. An application wishing to use certficates from other providers may use methods convertCertificateChain and convertToAttributeCertificateChain of the IAIK-JCE crypto toolkit for converting them into the IAIK X.509 representation before using them with IAIK-CMS. Please note that both, iaik.x509.X509Certificate and iaik. x509.attr.AttributeCertificate fit into the JCA certificate API because being descendants of class java.security.cert.Certificate. Unfortunately java.security.cert.Certificate only groups public key certificates; so iaik.x509.attr.AttributeCertificate returns null when calling method getPublicKey.
  • Most of the getEngine methods of the SecurityProvider class does not specify the requested engine by its name; rather the engines are requested by its AlgorithmIDs as used with CMS
  • Wheras  iSaSiLk consults the SecurityProvider for getting the required -- if necessary -- initialized engine and subsequently performs the cryptographic operation on the engine itself, IAIK-CMS -- where appropriate -- allows the SecurityProvider to do the whole cryptographic task. This shall give an SecurityProvider implementing application more independence in how to perform the cryptographic operation. When, for instance, allowing the SecurityProvider to calcualte a RSA signature value, the specific SecurityProvider implementation itself may decide to use a Cipher or Signature engine or any other way to get the Signature value (e.g. from a Smartcard). This concept provides more flexibility, but sometimes may require some knowledge about the way the CMS protocol expects a cryptographic operation has to be performed. However, in general you may not have to take care about the IAIK-CMS SecurityProvider at all because you simply can use the default SecurityProvider.

Class iaik.cms.SecurityProvider is the main class of the IAIK-CMS SecurityProvider model. It itself provides default implementations for most of the cryptographic operations required by CMS, expect for functionalities that are not available from JCA/JCE engines by default, like, for instance, Ephemeral Static Diffie Hellman. Unfortunately there is no general way to initialize a KeyPairGenerator with algorithm parameters as required when creating a originator ESDH key pair with domain parameters matching to those of the recipient´s public key. So the default implementation of method generateKeyAgreementKeyPair(AlgorithmID keyAgreeAlgorithm, PublicKey otherKey) has to throw an exception and has to be implemented if using another cryptographic provider than IAIK. The same applies to method createSharedKeyEncryptionKey which cannot handle an ESDHKeyAgreement in provider independent way. So at the current state it might be preferable to override all ESDH related methods when intending to use another provider than IAIK.

With class IaikProvider IAIK-CMS contains an SecurityProvider implemention for the IAIK cryptography provider of the crypto toolkit IAIK-JCE. Please note the difference: The IAIK provider is a JCA/JCE cryptography provider supplying cryptographic engines; Class IaikProvider is an IAIK-CMS SecurityProvider implementation that makes the cryptographic engines of the IAIK JCA/JCE cyrptography provider available for IAIK-CMS.
Per default IAIK-CMS is configured to look if the IAIK cryptography provider is available. If yes, it uses the IaikProvider as SecurityProvider. If not it uses the default SecurityProvider implementation. Thus if you want to use the IAIK provider you do not have to take any care about the SecurityProvider setting. However, if you do not want to use the IAIK provider for some reasons (e.g. you require a specific, e.g. smartcard depending, handling for some tasks) you have two options:

Use the default SecurityProvider implementation by setting it as SecurityProvider to be used

SecurityProvider.setSecurityProvider(new SecurityProvider());

Implement your own SecurityProvider for the required cryptographic tasks and install it as SecurityProvider to be used:

MySecurityProvider mySecurityProvider = ...;
SecurityProvider.setSecurityProvider(mySecurityProvider);

If choosing the second option from above basically you may follow one of two ways for implementing your own SecurityProvider:

  1. You want to mainly use the IAIK JCE as a cryptography provider and use another provider just for a few algorithms. For example, you want to use a smartcard requiring a particular handling for RSA signature calculatuion.
  2. You do not want to use the IAIK JCE at all and use only some other provider.

In the first case you may extend the IaikProvider class, e.g.:


public class MySecurityProvider extends IaikProvider {
  ...
  public byte[] calculateSignatureFromSignedAttributes(
      AlgorithmID signatureAlgorithm, 
      AlgorithmID digestAlgorithm, 
      PrivateKey privateKey, 
      byte[] signedAttributes) 
   throws NoSuchAlgorithmException,
             InvalidKeyException,
             SignatureException {
    byte[] signatureValue = null;
    // get the implementation name: RSA? 
    String implementationName = 
       signatureAlgorithm.getImplementationName();
    if (implementationName == IMPLEMENTATION_NAME_RSA) {
      // let the smartcard calculate the signature value
      byte[] signatureValue = ...; 
    } else {
      signatureValue = 
         super.calculateSignatureFromSignedAttributes(
                    signatureAlgorithm, 
                    digestAlgorithm, 
                    privateKey, 
                    signedAttributes);
    } 
    return signatureValue;
  } 
}

If the smartcard or HSM your are using supports the PKCS#11 standard, you may use our PKCS#11 provider to access it from your Java™ application.

In the second case, if you want to use a different provider alltogether and not use the IAIK-JCE at all (for whatever reason ;-) you may start with the SecurityProvider class and override those methods where you cannot use the default implementation.
Note that you also may install a SecurityProvider per CMS object. To, for instance, use one specific SecurityProvider only for one specific SignedDataStream object, you may use its setSecurityProvider method, e.g.:

MySecurityProvider myProvider = ...; 
SignedDataStream signedData = ...; 
signedData.setSecurityProvider(myProvider);

Now myProvider will be used for any cryptographic operation required by this one specific SignedDataStream object. If any of the CMS objects (SignerInfos) belonging to this SignedDataStream object needs a SecurityProvider, it will use myProvider, too; except for those, who already have installed their own SecurityProvider. However, SecurityProviders are only forwarded from "higher" to "lower" objects, e.g.: if a SignedData(Stream) object has its own SecurityProvider it forwards it to its SignerInfos objects (as long as they do not already have their own SecurityProviders), but if a SignerInfo with its own SecurityProvider is added to a SignedData(Stream) object that has no SecurityProvider installed, the SecurityProvider of the SignerInfo is not forwarded to the SignedData(Stream) object. In this case the SignedDataStream object will use the default, system-wide installed SecurityProvider (which should be available in any case).

If you want to use a specific SecurityProvider for a specific CMS object please look at the Javadoc™ if you may add it by using method setSecurityProvider (if present), or if you already may install it via the constructor (which may required when, for instance, parsing a CMS object that needs cryptographic engines already during the parsing procedure (e.g. for digest calculation initialization when parsing a SignedData object)).

 

print Print