2015-02-24 20 views
5

Để ký giấy chứng nhận trong OpenSSL, tôi sử dụng chức năng X509_sign() bằng cách cho ăn bằng yêu cầu (như X509_REQ*), khóa ký và thông báo.Giấy chứng nhận đăng nhập trong PKCS # 11

Bây giờ tôi có khóa ký của tôi được lưu trữ trong HSM, vì vậy tôi không thể trích xuất nó để ký chứng chỉ. Rất tiếc, PKCS # 11 không cung cấp tương đương với X509_sign(). Tất cả nó có là C_Sign()/C_SignUpdate()/C_SignFinal() họat động của các hàm hoạt động trên dữ liệu thô chứ không phải trên chứng chỉ.

Ai đó có thể giúp tôi với mã C/C++ mẫu cách sử dụng PKCS # 11 để ký giấy chứng nhận được tạo bằng OpenSSL không?

Trả lời

4

Mã bên dưới ký hiệu cấu trúc X509 * đã cho trong HSM. Xử lý lỗi bị bỏ qua vì mục đích rõ ràng.

void signCertInHsm(X509* x509, unsigned long pkcs11SigningAlgo, CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE p11session, CK_OBJECT_HANDLE pkcs11PrivKeyHandle) 
{ 
    x509->cert_info->enc.modified = 1; 

    // set signature algorithm in the certificate 
    if (x509->cert_info->signature) 
    { 
     const int signingAlgoNid = pkcs11SignatureAlgorithmToNid(pkcs11SigningAlgo); 
     X509_ALGOR_set0(x509->cert_info->signature, OBJ_nid2obj(signingAlgoNid), V_ASN1_NULL, NULL); 
    } 
    if (x509->sig_alg) 
    { 
     const int signingAlgoNid = pkcs11SignatureAlgorithmToNid(pkcs11SigningAlgo); 
     X509_ALGOR_set0(x509->sig_alg, OBJ_nid2obj(signingAlgoNid), V_ASN1_NULL, NULL); 
    } 

    // DER-encode certificate 
    unsigned char *certDerBuf = NULL; 
    const size_t certDerLen = ASN1_item_i2d((ASN1_VALUE*)x509->cert_info, &certDerBuf, ASN1_ITEM_rptr(X509_CINF)); 

    CK_MECHANISM mechanism = { pkcs11SigningAlgo, NULL_PTR, 0 }; 
    p11->C_SignInit(p11session, &mechanism, pkcs11PrivKeyHandle); 

    // determine signature size 
    CK_ULONG signatureSize = 0; 
    p11->C_Sign(p11session, certDerBuf, certDerLen, NULL, &signatureSize); 

    // sign 
    if (x509->signature->data) 
     OPENSSL_free(x509->signature->data); 
    x509->signature->data = (unsigned char*)OPENSSL_malloc(signatureSize); 
    x509->signature->length = signatureSize; 
    p11->C_Sign(p11session, certDerBuf, certDerLen, x509->signature->data, &signatureSize); 

    x509->signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); 
    x509->signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; 

    OPENSSL_free(certDerBuf); 
} 

int pkcs11SignatureAlgorithmToNid(unsigned long algo) 
{ 
    switch(algo) 
    { 
    case CKM_SHA1_RSA_PKCS: return NID_sha1WithRSAEncryption; 
    case CKM_SHA256_RSA_PKCS: return NID_sha256WithRSAEncryption; 
    //... add more mappings that your app supports 
    default: throw std::invalid_argument("Not supported signature algorithm"); 
    } 
} 
+0

Câu trả lời hay, Andrei! Chính xác đến mức và làm những gì nó được cho là phải làm. –

Các vấn đề liên quan