Menu

ICrypto Interface

yorick.flannagan

A interface ICrypto

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:

  1. Enumerar os slots criptográficos com enumerateSlots();
  2. Para um dado slot criptográfico selecionado:
    • enumerar os mecanismos suportados do tipo desejado com enumerateMechanisms();
    • verificar, se não selecionado da enumeração anterior, se um mecanismo específico é suportado com isMechanismSupported();
    • na geração de chaves criptográficas, verificar se um determinado tamanho de chave é suportado com isKeySupported();
  3. Gerar as chaves criptográficas e assinar uma requisição PKCS#10 com generateCSR();
  4. Após a assinatura do certificado pela Autoridade Certificadora, instalá-no no slot com installCertificate().

Related

Wiki: Home

MongoDB Logo MongoDB