Skip to content

Commit df2fb37

Browse files
committed
Change profile decoding
1 parent f7a5128 commit df2fb37

1 file changed

Lines changed: 37 additions & 68 deletions

File tree

StikJIT/idevice/profiles.m

Lines changed: 37 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
//
77
#include "profiles.h"
88
@import Foundation;
9-
@import Security;
109

1110
NSError* makeError(int code, NSString* msg) {
1211
return [NSError errorWithDomain:@"profiles" code:code userInfo:@{NSLocalizedDescriptionKey: msg}];
@@ -91,87 +90,57 @@ bool addProfile(IdeviceProviderHandle* provider, NSData* profile, NSError** erro
9190
return true;
9291
}
9392

94-
typedef CFTypeRef CMSDecoderRef;
95-
OSStatus CMSDecoderCreate(CMSDecoderRef * cmsDecoderOut);
96-
OSStatus CMSDecoderUpdateMessage(CMSDecoderRef cmsDecoder, const void * msgBytes, size_t msgBytesLen);
97-
OSStatus CMSDecoderFinalizeMessage(CMSDecoderRef cmsDecoder);
98-
OSStatus CMSDecoderCopyContent(CMSDecoderRef cmsDecoder, CFDataRef * contentOut);
99-
OSStatus CMSDecoderCopyAllCerts(CMSDecoderRef cmsDecoder, CFArrayRef * certsOut);
100-
101-
102-
// Helper to convert OSStatus -> NSError
103-
static NSError *NSErrorFromOSStatus(OSStatus status, NSString *message) {
104-
if (status == errSecSuccess) return nil;
105-
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: message ?: @"Security error",
106-
@"OSStatus" : @(status) };
107-
return [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:userInfo];
108-
}
109-
110-
11193
@implementation CMSDecoderHelper
11294

11395
+ (NSData*)decodeCMSData:(NSData *)cmsData
11496
// outCerts:(NSArray<id> * _Nullable * _Nullable)outCerts
11597
error:(NSError * _Nullable * _Nullable)error
11698
{
117-
if (!cmsData) {
118-
if (error) *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSURLErrorBadURL userInfo:@{NSLocalizedDescriptionKey: @"cmsData is nil"}];
99+
if (!cmsData || cmsData.length == 0) {
100+
if (error) {
101+
*error = [NSError errorWithDomain:NSCocoaErrorDomain
102+
code:NSURLErrorBadURL
103+
userInfo:@{NSLocalizedDescriptionKey: @"Invalid or empty CMS payload"}];
104+
}
119105
return nil;
120106
}
121107

122-
CMSDecoderRef decoder = NULL;
123-
OSStatus status = CMSDecoderCreate(&decoder);
124-
if (status != errSecSuccess || decoder == NULL) {
125-
if (error) *error = NSErrorFromOSStatus(status, @"Failed to create CMS decoder");
126-
return nil;
108+
NSData *xmlStart = [@"<?xml" dataUsingEncoding:NSASCIIStringEncoding];
109+
NSData *plistEnd = [@"</plist>" dataUsingEncoding:NSASCIIStringEncoding];
110+
NSData *binaryMagic = [@"bplist00" dataUsingEncoding:NSASCIIStringEncoding];
111+
112+
if (xmlStart && plistEnd) {
113+
NSRange searchRange = NSMakeRange(0, cmsData.length);
114+
NSRange startRange = [cmsData rangeOfData:xmlStart options:0 range:searchRange];
115+
if (startRange.location != NSNotFound) {
116+
NSUInteger remainingLength = cmsData.length - startRange.location;
117+
NSRange endSearchRange = NSMakeRange(startRange.location, remainingLength);
118+
NSRange endRange = [cmsData rangeOfData:plistEnd options:0 range:endSearchRange];
119+
if (endRange.location != NSNotFound) {
120+
NSUInteger plistStart = startRange.location;
121+
NSUInteger plistEndIndex = NSMaxRange(endRange);
122+
if (plistEndIndex > plistStart && plistEndIndex <= cmsData.length) {
123+
NSRange plistRange = NSMakeRange(plistStart, plistEndIndex - plistStart);
124+
return [cmsData subdataWithRange:plistRange];
125+
}
126+
}
127+
}
127128
}
128129

129-
// Feed data to decoder
130-
status = CMSDecoderUpdateMessage(decoder, cmsData.bytes, cmsData.length);
131-
if (status != errSecSuccess) {
132-
if (error) *error = NSErrorFromOSStatus(status, @"Failed to update CMS decoder with message bytes");
133-
CFRelease(decoder);
134-
return nil;
130+
if (binaryMagic) {
131+
NSRange binaryRange = [cmsData rangeOfData:binaryMagic options:0 range:NSMakeRange(0, cmsData.length)];
132+
if (binaryRange.location != NSNotFound) {
133+
NSRange plistRange = NSMakeRange(binaryRange.location, cmsData.length - binaryRange.location);
134+
return [cmsData subdataWithRange:plistRange];
135+
}
135136
}
136137

137-
// Finalize (parse) the message
138-
status = CMSDecoderFinalizeMessage(decoder);
139-
if (status != errSecSuccess) {
140-
if (error) *error = NSErrorFromOSStatus(status, @"Failed to finalize CMS message");
141-
CFRelease(decoder);
142-
return nil;
143-
}
144-
145-
// Extract the content (the inner payload). This may be NULL if content is detached.
146-
CFDataRef contentData = NULL;
147-
status = CMSDecoderCopyContent(decoder, &contentData);
148-
if (status != errSecSuccess && status != errSecItemNotFound) {
149-
// errSecItemNotFound could mean no content (detached signature)
150-
if (error) *error = NSErrorFromOSStatus(status, @"Failed to copy CMS content");
151-
if (contentData) CFRelease(contentData);
152-
CFRelease(decoder);
153-
return nil;
138+
if (error) {
139+
*error = [NSError errorWithDomain:NSCocoaErrorDomain
140+
code:NSFileReadUnknownError
141+
userInfo:@{NSLocalizedDescriptionKey: @"Unable to extract plist from CMS payload"}];
154142
}
155-
156-
// // Extract embedded certificates (if any)
157-
// CFArrayRef certsArray = NULL;
158-
// status = CMSDecoderCopyAllCerts(decoder, &certsArray);
159-
// if (status == errSecSuccess && certsArray) {
160-
// // certsArray contains SecCertificateRef items
161-
// NSArray *certs = (__bridge_transfer NSArray *)certsArray;
162-
// if (outCerts) *outCerts = certs;
163-
// } else {
164-
// // no certs or error
165-
// if (status != errSecSuccess && status != errSecItemNotFound) {
166-
// if (error) *error = NSErrorFromOSStatus(status, @"Failed to copy embedded certificates (if any)");
167-
// CFRelease(decoder);
168-
// return NO;
169-
// }
170-
// if (outCerts) *outCerts = @[]; // empty
171-
// }
172-
173-
CFRelease(decoder);
174-
return (__bridge NSData *)(contentData);
143+
return nil;
175144
}
176145

177146
@end

0 commit comments

Comments
 (0)