Экспорт открытого ключа SecKeyRef в формате X509 - PullRequest
0 голосов
/ 16 декабря 2018

Привет. Я пытался экспортировать формат открытого ключа в виде сертификата x509 для отправки на сервер.в то время как я генерировал его обычным способом, он работает хорошо, но после попытки добавить формат этой функцией

SecTrustCreateWithCertificates

для открытого ключа происходит сбой!

+(NSDictionary *)generatePublicAndPrivate {

    NSMutableDictionary *result = [[NSMutableDictionary alloc]init];

    OSStatus status = noErr;
    NSMutableDictionary *privateKeyAttr = [[NSMutableDictionary alloc] init];
    NSMutableDictionary *publicKeyAttr = [[NSMutableDictionary alloc] init];
    NSMutableDictionary *keyPairAttr = [[NSMutableDictionary alloc] init];

    NSData * publicTag = [NSData dataWithBytes:publicKeyIdentifier length:strlen((const char *)publicKeyIdentifier)];
    NSData * privateTag = [NSData dataWithBytes:privateKeyIdentifier length:strlen((const char *)privateKeyIdentifier)];
    SecKeyRef publicKey = NULL;
    SecKeyRef privateKey = NULL;

    [keyPairAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
    [keyPairAttr setObject:[NSNumber numberWithInt:2048] forKey:(id)kSecAttrKeySizeInBits];

    [privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
    [privateKeyAttr setObject:privateTag forKey:(id)kSecAttrApplicationTag];

    [publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
    [publicKeyAttr setObject:publicTag forKey:(id)kSecAttrApplicationTag];

    [keyPairAttr setObject:privateKeyAttr forKey:(id)kSecPrivateKeyAttrs];
    [keyPairAttr setObject:publicKeyAttr forKey:(id)kSecPublicKeyAttrs];

    status = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr, &publicKey, &privateKey);
    NSData* publicData = [NSData dataWithBytes:publicKey length:SecKeyGetBlockSize(publicKey)];
    NSData* privateData = [NSData dataWithBytes:privateKey length:SecKeyGetBlockSize(privateKey)];

    SecCertificateRef certificateRef = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)publicData);
    SecPolicyRef policyRef = SecPolicyCreateBasicX509();
    SecTrustRef trustRef;

    OSStatus statusForPublic = SecTrustCreateWithCertificates(certificateRef, policyRef, &trustRef);
    NSAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates failed.");

    SecTrustResultType trustResult;
    statusForPublic = SecTrustEvaluate(trustRef, &trustResult);
    NSAssert(status == errSecSuccess, @"SecTrustEvaluate failed.");

    SecKeyRef publicKeyWithX509Certififcate = SecTrustCopyPublicKey(trustRef);
    NSAssert(publicKeyWithX509Certififcate != NULL, @"SecTrustCopyPublicKey failed.");

    NSData* publicDataWithX509Certificate = [NSData dataWithBytes:publicKey length:SecKeyGetBlockSize(publicKey)];

    [result setValue:[publicDataWithX509Certificate base64EncodedStringWithOptions:0] forKey:@"public"];
    [result setValue:[privateData base64EncodedStringWithOptions:0] forKey:@"private"];

    VALSecureEnclaveValet *oneTimePassword = [[VALSecureEnclaveValet alloc] initWithIdentifier:@"ResalatOneTimePassword" accessControl:VALAccessControlUserPresence];

    [oneTimePassword setValue:CFBridgingRelease(privateKey) forKey:@"PrivateKeyObject"];
    [oneTimePassword setString:[NSString stringWithFormat:@"%@", [privateData base64EncodedStringWithOptions:0]] forKey:@"OneTimePrivateKey"];
    [Functions saveNSUSERData:@"PublicKey" ValueData:[publicData base64EncodedStringWithOptions:0]];

    return result;
}
...