A interface ICrypto, proposta em caráter experimental, visa especificar um único modelo para as operações criptográficas normalmente utilizadas no âmbito da ICP-Brasil, a saber: a emissão de novos certificados (certificate enrollment) pelas aplicações das Autoridades Certificadoras e a assinatura (e verificação) de documentos por entidades usuárias. Presentemente, a interface está implementada somente para as operações de enrollment.
Escolhemos implementar uma inteface sem estado de modo a simplificar o acesso às diferentes implementações de objetos criptográficos expostos pelos navegadores suportados. Por outro lado, a interface incorpora a semântica da especificação RSA Labs PKcS#11 por razões puramente religiosas: trata-se de um padrão aberto e não um modelo proprietário...
A interface está especificada e documentada como segue, utilizando as convenções da XPIDL:
#include "nsISupports.idl"
#include "nsIArray.idl"
[scriptable, uuid(f9ce2f46-affd-4a36-8cbf-b42db76ccea3)]
interface ICrypto: nsISupports
{
/*
* Enumerate all present cryptographic slots.
* Returns an array of slot names.
*/
void enumerateSlots(
retval out nsIArray slots
);
/*
* Enumerate cryptographic mechanisms supported by specified slot
* Arguments:
* slot: slot name (a choice from enumerateSlots()).
* mechTypes: mechanism type. Must be a xor of one or more of the following values (by convenience,
* 0x00 means all mechanisms):
* 0x01 = generate key pair mechanisms
* 0x02 = signing mechanisms
* 0x04 = encryption mechanisms
* 0x08 = wrap key mechanisms
* 0x20 = derive key mechanisms
* 0x40 = digest mechanisms
* 0x80 = sign & recover mechanisms
* Returns an array of mechanisms (as defined in PKCS#11).
*/
void enumerateMechanisms(
in string slot,
in unsigned long mechTypes,
retval out nsIArray mechanisms
);
/*
* Checks if specified mechanism is supported by token
* Arguments:
* slot: slot name (a choice from enumerateSlots()
* mechanism: PKCS#11 mechanism type code (a choice from enumerateMechanisms())
* Returns true if mechanism is supported.
*/
void isMechanismSupported(
in string slot,
in unsigned long mechanism,
retval out boolean is
);
/*
* Checks if specified key size is supported by given mechanism
* Arguments:
* slot: slot name (a choice from enumerateSlots()
* mechanism: PKCS#11 mechanism type code (a choice from enumerateMechanisms() of the type 0x01)
* keySize: the desired key size
* Returns true if key size is supported by mechanism
*/
void isKeySupported(
in string slot,
in unsigned long mechanism,
in unsigned long keySize,
retval out boolean is
);
/*
* Create a certificate signing request
* Arguments:
* slot: slot name (a choice from enumerateSlots())
* keypairMechanism: PKCS#11 mechanism type code (a choice from enumerateMechanisms()). Must be a key pair mechanism.
* signMechanism: PKCS#11 mechanism type code (a choice from enumerateMechanisms()). Must be a signing mechanism.
* keySize: Key size (must match getMechanismInfo() result).
* dn: Subject certificate distinguished name.
* Returns a base64 coded PKCS#10 request.
*/
void generateCSR(
in string slot,
in unsigned long keypairMechanism,
in unsigned long signMechanism,
in unsigned long keySize,
in string dn,
retval out string pkcs10
);
/*
* Install a signed certificate (the request should be signed by generateCSR()).
* Arguments:
* slot: slot name (the same as generateCSR())
* pkcs7: the PKCS#7 to install
* encoding: the PKCS#7 encoding scheme. Optional. Default: UTF-8.
*/
void installCertificate(
in string slot,
in string pkcs7,
optional in string encoding
);
};
Do ponto de vista prático, os conceitos PKCS#11 de slot e mecanismo, aqui utilizados, são diretamente mapeáveis nos conceitos de provedor de serviços criptográficos e algoritmo utilizados pelo MS Windows. Porém, a principal dificuldade do modelo está na categorização dos mecanismos criptográficos, que não têm implementações consistentes nas diferentes bibliotecas criptográficas disponíveis para os navegadores. Assim é que não fomos capazes de encontrar uma representação única para os algoritmos criptográficos suportados. Na MS CryptoAPI, utilizada pelo IE sob o Windows XP, os mecanismos são incluídos em categorias distintas das utilizadas na CNG API, utilizada a partir do Windows Vista, ambas incompatíveis entre si, mas mapeáveis no que é necessário para as necessidades do projeto. Por outro lado, as API's representam de modo distinto os mesmos algoritmos criptográficos, dificultando este mapeamento. O problema é que tal representação não é mapeável com a representação utilizada na especificação PKCS#11.
A solução adotada na implementação em JavaScript de referência não é inteiramente satisfatória e isso se refletiu no modelo básico de utilização da biblioteca proposta no processo de enrollment: