Криптотокен 2 ЭП

Пример формирования подписи формата PKCS#7 для токена Криптотокен 2 ЭП (pkcs7SignData).

id<JCToken> token = ...;

// 1. Получение сертификата по заданному идентификатору

// Идентификатор (CKA_ID)
NSData* certificateID = ...;

// 1.1. Получение списка сертификатов
JCCertificateListResult *certificatesResult = [token readCertificates];
if (certificatesResult.error) {
    // 1.2. Обработка ошибки получения списка сертификатов
    return;
}

// 1.3. Поиск сертификата по заданному идентификатору
NSUInteger index = [certificatesResult.value indexOfObjectPassingTest:^BOOL(id<JCCertificateObject> _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    return [obj.identifier isEqualToData:certificateID];
}];

if (index == NSNotFound) {
    // 1.2. Обработка отсутствия сертификата
    return;
}

id<JCCertificateObject> certificate = certificatesResult.value[index];

// 2. Логин с PIN-кодом пользователя

// PIN-код пользователя
NSString* userPIN = ...;

JCResult *loginResult = [token loginByUserPIN:userPIN];
if(loginResult.error) {
    // 2.1. Обработка ошибки
    return;
}

// 3. Формирование подписи PKCS#7
NSData* data = ...;
BOOL attachedSignature = ...;
NSString* signaturePIN = ...;
JCDataResult *signResult = [[token asJCTokenCT2] pkcs7SignData:data
                                                   certificate:certificate
                                             attachedSignature:attachedSignature
                                                  signaturePIN:signaturePIN];

// 4. Логаут
JCResult *logoutResult = [token logout];

if (signResult.error) {
    // 5. Если требуется ввести PIN-код подписи, то необходимо предоставить такую возможность
    BOOL isSignaturePINRequared = NO;
    if(signResult.error.domain == JCErrorDomain &&
       signResult.error.code == JCErrorPKCS11Error &&
       [signResult.error.userInfo[JCErrorPKCS11ResultCodeNameKey] isEqualToString:@"CKR_SIGNATURE_PIN_INCORRECT"])
    {
        isSignaturePINRequared = YES;
    }

    if(!isSignaturePINRequared) {
        // 5.1. Не требуется ввод PIN-кода подписи.
        // Обработка ошибки формирования подписи
        return
    }
    // 5.2. Требуется ввод PIN-кода подписи.
    // Запросить у пользователя PIN-код подписи и вернуться к шагу 1
    return;
}
// 6. Обработка подписи
NSData* signature = signResult.value;