Skip to content

Commit c6c7d6d

Browse files
committed
Clean code
1 parent 9f36450 commit c6c7d6d

File tree

2 files changed

+51
-195
lines changed

2 files changed

+51
-195
lines changed

ios/TcpSocketClient.m

Lines changed: 49 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -597,11 +597,13 @@ - (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert
597597
settings:(NSDictionary *)settings {
598598
RCTLogWarn(@"createIdentity: Starting identity creation");
599599

600+
SecIdentityRef identity = NULL;
601+
600602
// Strip PEM headers and convert to data
601603
NSString *cleanedCert = [self stripPEMHeader:pemCert prefix:@"CERTIFICATE"];
602604
NSString *cleanedPrivateKey = [self stripPEMHeader:pemKey prefix:@"PRIVATE KEY"];
603605
NSString *certAlias = settings[@"certAlias"];
604-
NSString *keyAlias= settings[@"keyAlias"];
606+
NSString *keyAlias = certAlias; // On iOS we must use the same label to create an identity
605607

606608
NSData *certData = [[NSData alloc] initWithBase64EncodedString:cleanedCert
607609
options:NSDataBase64DecodingIgnoreUnknownCharacters];
@@ -620,18 +622,17 @@ - (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert
620622
return NULL;
621623
}
622624

623-
// Extract RSA key from PKCS#8 - TODO use a ASN1 decoder to detect the key format ...
624-
// For my own use I know it's a pem but I prefer not to trust a file extension and
625-
// it's better to check from asn1 data
625+
// Extract RSA key from PKCS#8
626+
// For my own use I know it's a pem but it would be better to not trust a file extension and
627+
// TODO use a ASN1 decoder to detect the key format ...
626628
NSData *rsaKeyData = [self extractRSAKeyFromPKCS8:pkcs8KeyData];
627629
if (!rsaKeyData) {
628630
RCTLogWarn(@"Failed to extract RSA key from PKCS#8");
629631
CFRelease(cert);
630632
return NULL;
631633
}
632-
634+
633635
NSDictionary *privateKeyAttributes = @{
634-
//(__bridge id)kSecClass: (__bridge id)kSecClassKey,
635636
(__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeRSA,
636637
(__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassPrivate,
637638
//(__bridge id)kSecAttrLabel: kKeychainPrivateKeyLabel,
@@ -655,35 +656,11 @@ - (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert
655656
};
656657
SecItemDelete((__bridge CFDictionaryRef)deleteKeyQuery);
657658

658-
// Import certificate in keychain
659-
NSDictionary *deleteCertQuery = @{
660-
(__bridge id)kSecClass: (__bridge id)kSecClassCertificate,
661-
(__bridge id)kSecAttrLabel: certAlias
662-
};
663-
SecItemDelete((__bridge CFDictionaryRef)deleteCertQuery);
664-
665-
NSDictionary *certAttributes = @{
666-
(__bridge id)kSecClass: (__bridge id)kSecClassCertificate,
667-
(__bridge id)kSecValueRef: (__bridge id)cert,
668-
(__bridge id)kSecAttrLabel: certAlias
669-
};
670-
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)certAttributes, NULL);
671-
if (status != errSecSuccess && status != errSecDuplicateItem) {
672-
RCTLogWarn(@"createIdentity: Failed to store certificate, status: %d", (int)status);
673-
CFRelease(cert);
674-
//CFRelease(privateKey);
675-
return NULL;
676-
}
677-
678659
// Add the private key to keychain
679660
NSDictionary *keyAttributes = @{
680661
(__bridge id)kSecClass: (__bridge id)kSecClassKey,
681662
(__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeRSA,
682663
(__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassPrivate,
683-
//(__bridge id)kSecValueData: keyData,
684-
//(__bridge id)kSecReturnPersistentRef: @YES,
685-
//(__bridge id)kSecAttrKeySizeInBits: @(keySize),
686-
//(__bridge id)kSecAttrIsPermanent: @YES,
687664
//(__bridge id)kSecAttrAccessible: (__bridge id)kSecAttrAccessibleAfterFirstUnlock,
688665
(__bridge id)kSecAttrLabel: keyAlias,
689666
//(__bridge id)kSecAttrApplicationTag: [kKeychainApplicationTag dataUsingEncoding:NSUTF8StringEncoding],
@@ -693,72 +670,52 @@ - (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert
693670
if (status != errSecSuccess && status != errSecDuplicateItem) {
694671
RCTLogWarn(@"createIdentity: Failed to store private key, status: %d", (int)status);
695672
CFRelease(cert);
696-
//CFRelease(privateKey);
673+
CFRelease(privateKey);
697674
return NULL;
698675
}
676+
677+
// Import certificate in keychain
678+
NSDictionary *deleteCertQuery = @{
679+
(__bridge id)kSecClass: (__bridge id)kSecClassCertificate,
680+
(__bridge id)kSecAttrLabel: certAlias
681+
};
682+
SecItemDelete((__bridge CFDictionaryRef)deleteCertQuery);
699683

700-
// Try to retrieve private key from keychain
701-
// NSDictionary *privateKeyQuery = @{
702-
// (__bridge id)kSecClass: (__bridge id)kSecClassKey,
703-
// (__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitOne,
704-
// (__bridge id)kSecReturnRef: @YES,
705-
// (__bridge id)kSecReturnData: @YES,
706-
// (__bridge id)kSecAttrLabel: @"My PrivateKey",
707-
// //(__bridge id)kSecAttrApplicationTag: [kKeychainApplicationTag dataUsingEncoding:NSUTF8StringEncoding],
708-
// //(__bridge id)kSecUseDataProtectionKeychain: @YES
709-
// };
710-
// SecKeyRef privateKey = NULL;
711-
// status = SecItemCopyMatching((__bridge CFDictionaryRef)privateKeyQuery, (CFTypeRef *)&privateKey);
712-
713-
// Add the certificate to keychain
714-
// NSDictionary *certAttributes = @{
715-
// (__bridge id)kSecClass: (__bridge id)kSecClassCertificate,
716-
// (__bridge id)kSecValueRef: (__bridge id)cert,
717-
// (__bridge id)kSecAttrLabel: kKeychainCertificateLabel
718-
// };
719-
//
720-
// status = SecItemAdd((__bridge CFDictionaryRef)certAttributes, NULL);
721-
// if (status != errSecSuccess && status != errSecDuplicateItem) {
722-
// RCTLogWarn(@"createIdentity: Failed to store certificate, status: %d", (int)status);
723-
// CFRelease(cert);
724-
// CFRelease(privateKey);
725-
// return NULL;
726-
// }
727-
728-
// // Query for the identity with correct attributes
729-
// NSDictionary *identityQuery = @{
730-
// (__bridge id)kSecClass: (__bridge id)kSecClassIdentity,
731-
// (__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitOne,
732-
// (__bridge id)kSecReturnRef: @YES,
733-
// //(__bridge id)kSecAttrLabel: @"My Certificate",
734-
// //(__bridge id)kSecUseDataProtectionKeychain: @YES
735-
// };
736-
NSDictionary *identityQuery = @{
737-
(__bridge id)kSecClass: (__bridge id)kSecClassIdentity,
738-
(__bridge id)kSecReturnRef: @YES,
739-
(__bridge id)kSecMatchItemList:@[(__bridge id)cert],
740-
(__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitOne,
741-
//(__bridge id)kSecAttrLabel: @"My Certificate",
742-
//(__bridge id)kSecUseDataProtectionKeychain: @YES
684+
NSDictionary *certAttributes = @{
685+
(__bridge id)kSecClass: (__bridge id)kSecClassCertificate,
686+
(__bridge id)kSecValueRef: (__bridge id)cert,
687+
(__bridge id)kSecAttrLabel: certAlias
743688
};
689+
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)certAttributes, NULL);
690+
if (status != errSecSuccess && status != errSecDuplicateItem) {
691+
RCTLogWarn(@"createIdentity: Failed to store certificate, status: %d", (int)status);
692+
CFRelease(cert);
693+
CFRelease(privateKey);
694+
return NULL;
695+
}
744696

745697

746-
// Query for the identity
747-
// NSDictionary *identityQuery = @{
748-
// (__bridge id)kSecClass: (__bridge id)kSecClassIdentity,
749-
// (__bridge id)kSecReturnRef: @YES,
750-
// (__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitOne
751-
// };
752698

753-
SecIdentityRef identity = NULL;
754-
identity = SecIdentityCreate(NULL, cert, privateKey);
755-
//status = SecItemCopyMatching((__bridge CFDictionaryRef)identityQuery, (CFTypeRef *)&identity);
756-
//
757-
// if (status != errSecSuccess || !identity) {
758-
// RCTLogWarn(@"createIdentity: Failed to find identity, status: %d", (int)status);
759-
// } else {
760-
// RCTLogWarn(@"createIdentity: Successfully found identity");
761-
// }
699+
//------ PRIVATE API: need to find the proper way of doing it -------
700+
if (NO) {
701+
identity = SecIdentityCreate(NULL, cert, privateKey);
702+
} else {
703+
NSDictionary *identityQuery = @{
704+
(__bridge id)kSecClass: (__bridge id)kSecClassIdentity,
705+
(__bridge id)kSecReturnRef: @YES,
706+
//(__bridge id)kSecMatchItemList:@[(__bridge id)cert],
707+
(__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitOne,
708+
(__bridge id)kSecAttrLabel: certAlias,
709+
//(__bridge id)kSecUseDataProtectionKeychain: @YES
710+
};
711+
status = SecItemCopyMatching((__bridge CFDictionaryRef)identityQuery, (CFTypeRef *)&identity);
712+
713+
if (status != errSecSuccess || !identity) {
714+
RCTLogWarn(@"createIdentity: Failed to find identity, status: %d", (int)status);
715+
} else {
716+
RCTLogWarn(@"createIdentity: Successfully found identity");
717+
}
718+
}
762719

763720
// Clean up
764721
CFRelease(cert);
@@ -829,6 +786,9 @@ - (NSDictionary *)getCertificate {
829786
return result;
830787
}
831788

789+
// We need an ASN1 decoder to parse properly but for my case I only need modulus and exponent
790+
// In addition SecCertificateCopyNormalizedIssuerSequence has some issues since it normalizes
791+
// issuer and we don't want that
832792
- (NSDictionary *)certificateToDict:(SecCertificateRef)certificate detailed:(BOOL)detailed {
833793
NSMutableDictionary *certInfo = [NSMutableDictionary dictionary];
834794

@@ -882,66 +842,6 @@ - (NSDictionary *)certificateToDict:(SecCertificateRef)certificate detailed:(BOO
882842
CFRelease(issuerSequence);
883843
}
884844

885-
// NSData *certData = (__bridge_transfer NSData *)SecCertificateCopyData(certificate);
886-
// if (certData) {
887-
//
888-
// }
889-
// // Get validity dates
890-
// CFDictionaryRef values = NULL;
891-
// status = SecCertificateCopyValues(certificate, NULL, &values);
892-
// if (status == errSecSuccess && values) {
893-
// CFDictionaryRef validityPeriod = CFDictionaryGetValue(values, kSecOIDValidityPeriod);
894-
// if (validityPeriod) {
895-
// CFArrayRef validityArray = CFDictionaryGetValue(validityPeriod, kSecPropertyKeyValue);
896-
// if (validityArray && CFArrayGetCount(validityArray) == 2) {
897-
// CFDictionaryRef notBeforeDict = CFArrayGetValueAtIndex(validityArray, 0);
898-
// CFDictionaryRef notAfterDict = CFArrayGetValueAtIndex(validityArray, 1);
899-
//
900-
// CFStringRef notBefore = CFDictionaryGetValue(notBeforeDict, kSecPropertyKeyValue);
901-
// CFStringRef notAfter = CFDictionaryGetValue(notAfterDict, kSecPropertyKeyValue);
902-
//
903-
// if (notBefore) {
904-
// NSDate *fromDate = (__bridge NSDate *)notBefore;
905-
// certInfo[@"valid_from"] = [self formatDate:fromDate];
906-
// }
907-
// if (notAfter) {
908-
// NSDate *toDate = (__bridge NSDate *)notAfter;
909-
// certInfo[@"valid_to"] = [self formatDate:toDate];
910-
// }
911-
// }
912-
// }
913-
//
914-
// // Check if it's a CA
915-
// CFDictionaryRef basicConstraints = CFDictionaryGetValue(values, kSecOIDBasicConstraints);
916-
// if (basicConstraints) {
917-
// CFTypeRef value = CFDictionaryGetValue(basicConstraints, kSecPropertyKeyValue);
918-
// if (value) {
919-
// certInfo[@"ca"] = @(CFBooleanGetValue(value));
920-
// }
921-
// }
922-
//
923-
// CFRelease(values);
924-
// }
925-
//
926-
// // Get serial number
927-
// NSData *serialData = (__bridge_transfer NSData *)SecCertificateCopySerialNumber(certificate, NULL);
928-
// if (serialData) {
929-
// NSMutableString *serialHex = [NSMutableString string];
930-
// const unsigned char *bytes = serialData.bytes;
931-
// for (NSInteger i = 0; i < serialData.length; i++) {
932-
// [serialHex appendFormat:@"%02X", bytes[i]];
933-
// }
934-
// certInfo[@"serialNumber"] = serialHex;
935-
// }
936-
//
937-
// // Get fingerprints
938-
// NSData *certData = (__bridge_transfer NSData *)SecCertificateCopyData(certificate);
939-
// if (certData) {
940-
// certInfo[@"fingerprint"] = [self calculateFingerprint:certData algorithm:CC_SHA1 length:CC_SHA1_DIGEST_LENGTH];
941-
// certInfo[@"fingerprint256"] = [self calculateFingerprint:certData algorithm:CC_SHA256 length:CC_SHA256_DIGEST_LENGTH];
942-
// certInfo[@"fingerprint512"] = [self calculateFingerprint:certData algorithm:CC_SHA512 length:CC_SHA512_DIGEST_LENGTH];
943-
// }
944-
945845
return certInfo;
946846
}
947847

@@ -1001,47 +901,6 @@ - (NSArray *)parseRSAPublicKey:(NSData *)keyData {
1001901
return @[modulus, exponent];
1002902
}
1003903

1004-
- (NSString *)calculateFingerprint:(NSData *)data algorithm:(unsigned char * (^)(const void *, CC_LONG, unsigned char *))hashFunction length:(CC_LONG)hashLength {
1005-
unsigned char digest[hashLength];
1006-
hashFunction(data.bytes, (CC_LONG)data.length, digest);
1007-
1008-
NSMutableString *fingerprint = [NSMutableString stringWithCapacity:hashLength * 3];
1009-
for (int i = 0; i < hashLength; i++) {
1010-
[fingerprint appendFormat:@"%02X:", digest[i]];
1011-
}
1012-
return [fingerprint substringToIndex:fingerprint.length - 1]; // Remove last colon
1013-
}
1014-
1015-
//- (NSDictionary *)parseDN:(NSDictionary *)dnDict {
1016-
// NSMutableDictionary *result = [NSMutableDictionary dictionary];
1017-
//
1018-
// // Map common DN fields
1019-
// NSDictionary *mapping = @{
1020-
// (id)kSecOIDCommonName: @"CN",
1021-
// (id)kSecOIDDNQualifier: @"dnQualifier"
1022-
// };
1023-
//
1024-
// for (id key in dnDict) {
1025-
// NSString *mappedKey = mapping[key];
1026-
// if (mappedKey) {
1027-
// NSString *value = dnDict[key];
1028-
// if ([value isKindOfClass:[NSString class]]) {
1029-
// result[mappedKey] = value;
1030-
// }
1031-
// }
1032-
// }
1033-
//
1034-
// return result;
1035-
//}
1036-
1037-
- (NSString *)formatDate:(NSDate *)date {
1038-
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
1039-
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
1040-
formatter.dateFormat = @"MMM dd HH:mm:ss yyyy 'GMT'";
1041-
formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
1042-
return [formatter stringFromDate:date];
1043-
}
1044-
1045904
- (NSError *)badInvocationError:(NSString *)errMsg {
1046905
NSDictionary *userInfo =
1047906
[NSDictionary dictionaryWithObject:errMsg

ios/TcpSockets.m

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,7 @@ - (TcpSocketClient *)createSocket:(nonnull NSNumber *)cId {
175175
[client resume];
176176
}
177177

178-
// Method with Promise (modern style)
179178
RCT_EXPORT_METHOD(getPeerCertificate:(nonnull NSNumber *)cId
180-
detailed:(BOOL)detailed
181179
resolver:(RCTPromiseResolveBlock)resolve
182180
rejecter:(RCTPromiseRejectBlock)reject) {
183181
TcpSocketClient *client = [self findClient:cId];
@@ -186,12 +184,11 @@ - (TcpSocketClient *)createSocket:(nonnull NSNumber *)cId {
186184
return;
187185
}
188186

189-
NSDictionary *cert = [client getPeerCertificate:detailed];
187+
NSDictionary *cert = [client getPeerCertificate];
190188
resolve(cert ?: [NSNull null]);
191189
}
192190

193191
RCT_EXPORT_METHOD(getCertificate:(nonnull NSNumber *)cId
194-
detailed:(BOOL)detailed
195192
resolver:(RCTPromiseResolveBlock)resolve
196193
rejecter:(RCTPromiseRejectBlock)reject) {
197194
TcpSocketClient *client = [self findClient:cId];
@@ -200,7 +197,7 @@ - (TcpSocketClient *)createSocket:(nonnull NSNumber *)cId {
200197
return;
201198
}
202199

203-
NSDictionary *cert = [client getCertificate:detailed];
200+
NSDictionary *cert = [client getCertificate];
204201
resolve(cert ?: [NSNull null]);
205202
}
206203

0 commit comments

Comments
 (0)