StCredZero / SCZ-BasicEncodingRules-iOS

Implementation of Basic Encoding Rules to enable import of RSA keys to iOS KeyChain using exponent & mod
39 stars 13 forks source link

ios 9 Public Key Generation Issue #6

Open BhawnaBhandari24 opened 9 years ago

BhawnaBhandari24 commented 9 years ago

In iOS 9 Apple is now correctly enforcing that public keys are preceded by a NULL byte when they are added to the keychain. Are we already handling this situation. As the public key getting created using the library is not getting added to the keychain in iOS9. Are we enforcing the library to verify that the public key modulus integer begins with 0x00?

Example : -----BEGIN PUBLIC KEY----- MIGIAoGA23zs5r8PQKpsKeoUd2Bjz3TJkUljWqMD8X98SaIb1LE7dCQzi9jwO58FGL0ieY1Dfnr9+g1iiY8sNzV+byawK98W9yFiopaghfoKtxXgUD8pi0fLPeWmAkntjn28Z/WZvvA265ELbBhphPXEJcFhdzUfgESHVuqFMEqp1pB+CP0CAwEAAQ== -----END PUBLIC KEY-----

Incorrect Ber Data : <30818802 8180db7c ece6bf0f 40aa6c29 ea147760 63cf74c9 9149635a a303f17f 7c49a21b d4b13b74 24338bd8 f03b9f05 18bd2279 8d437e7a fdfa0d62 898f2c37 357e6f26 b02bdf16 f72162a2 96a085fa 0ab715e0 503f298b 47cb3de5 a60249ed 8e7dbc67 f599bef0 36eb910b 6c186984 f5c425c1 6177351f 80448756 ea85304a a9d6907e 08fd0203 010001>

Correct Ber Data : <30818902 818100db7c ece6bf0f 40aa6c29 ea147760 63cf74c9 9149635a a303f17f 7c49a21b d4b13b74 24338bd8 f03b9f05 18bd2279 8d437e7a fdfa0d62 898f2c37 357e6f26 b02bdf16 f72162a2 96a085fa 0ab715e0 503f298b 47cb3de5 a60249ed 8e7dbc67 f599bef0 36eb910b 6c186984 f5c425c1 6177351f 80448756 ea85304a a9d6907e 08fd0203 010001>

zee-khalid commented 9 years ago

Hi guys, I am having the same issue with iOS9 when using this library. It generates the incorrect ber data and does not save the public key correctly. BhanwnaBhandari : do you have any idea on how to fix this? Do I need to change my public key modulus or some code change to get this working in iOS9?

bugman79 commented 9 years ago

I have the same problem, seems that in IOS 8.x Apple don't check the ber data. I see this post:

https://forums.developer.apple.com/thread/15129

And in fact if you try to save the der and check with dumpasn1tool is seems non correct.

sokol8 commented 9 years ago

Hi guys,

any ideas how to fix the lib?

bugman79 commented 9 years ago

To fix the lib is necessary to put a NULL value (0x00) before the bytes from modulus.

In this sample

00000000 30 81 89 02 81 81 00 be 6c 60 c3 81 36 f8 cc 4a |0.......l`..6..J| 00000010 2d dc c8 c7 02 fb d7 83 74 3e 2b d5 a3 e9 2b 6c |-.......t>+...+l| 00000020 57 5f 87 ef cb ae 1f b2 b1 ed df 8e c3 5d 67 e5 |W_...........]g.| 00000030 d6 2b 13 d0 8b 35 6f 45 4f 94 a0 95 7a bb 84 68 |.+...5oEO...z..h| 00000040 3f d4 14 b7 e3 ba 87 a1 bf 73 50 50 b6 9d ba 88 |?........sPP....| 00000050 8a 54 e9 ab 71 cb f1 3e 76 24 9d 02 90 62 52 80 |.T..q..>v$...bR.| 00000060 b7 4e 4b 99 82 49 24 e1 77 a3 17 d1 bd ac d2 1e |.NK..I$.w.......| 00000070 0e dd 5a 8d a7 27 ff cb c2 11 e3 a5 11 80 55 41 |..Z..'........UA| 00000080 ed 2d 4a 62 66 fa ab 02 03 01 00 01 |.-Jbf.......| 0000008c

30 81 89 is SEQUENCE (bytes = 137) After 02 81 81 is The INTEGER (129 bytes)

After is necessary to add a 0x00 value and then the modulus.

The lib instead after 02 81 81 start directly with the bytes of the modulus.

Adding the 0x00 make the public key correct and iOS 9 accept it.

StasRazbiegin commented 9 years ago

Bugman79, could you please tell where exactly you inserted your 0x00?

BhawnaBhandari24 commented 9 years ago

Bugman79, Could you please tell where exactly you inserted your 0x00? I tried the same but then SecKeyRawVerify check fails. If I am not wrong it should be same as used for signing the data.

zee-khalid commented 9 years ago

I am also trying to insert the 0x00 but not sure if I am doing at the right place. Bugman79 can you please help us out? A sample code would be helpful.

bugman79 commented 9 years ago

The 0x00 to insert is before the bytes of modulus, as a sample, in this way you can create a correct public key:

NSData modBits = modulus; NSData expBits = exponent;

NSMutableData *fullKey = [[NSMutableData alloc] initWithLength:6+[modBits length]+[expBits length]  +  1  ] ;
unsigned char *fullKeyBytes = [fullKey mutableBytes];
unsigned int bytep = 0; // current byte pointer
fullKeyBytes[bytep++] = 0x30;
if(4+[modBits length]+[expBits length] >= 128){
    fullKeyBytes[bytep++] = 0x81;
    [fullKey increaseLengthBy:1];
}
unsigned int seqLenLoc = bytep;
fullKeyBytes[bytep++] = 4+[modBits length]+[expBits length] +1 ;

fullKeyBytes[bytep++] = 0x02;

if([modBits length] >= 128){
    fullKeyBytes[bytep++] = 0x81;
    [fullKey increaseLengthBy:1];
    fullKeyBytes[seqLenLoc]++;
}
fullKeyBytes[bytep++] = [modBits length] +1;

// This is the NULL to add fullKeyBytes[bytep++] = 0x00;

[modBits getBytes:&fullKeyBytes[bytep] length:[modBits length]];

bytep += [modBits length];
fullKeyBytes[bytep++] = 0x02;
fullKeyBytes[bytep++] = [expBits length];

[expBits getBytes:&fullKeyBytes[bytep] length:[expBits length]];
StasRazbiegin commented 9 years ago

Guys, I have this code as simple as: const char fixByte = 0; NSMutableData * fixedModule = [NSMutableData dataWithBytes:&fixByte length:1]; [fixedModule appendData:modulusData];

And everything seems to be working fine. Bugman79, what do you think about it? Does it have any caveats?

bugman79 commented 9 years ago

Seems ok if you want to test the public key save as file and then use https://www.cs.auckland.ac.nz/~pgut001/dumpasn1.c To test if the key is correct.

StasRazbiegin commented 9 years ago

Thanks, good point. Looks like everything is correct: screen shot 2015-09-01 at 1 11 24 pm

altagir commented 8 years ago

Still struggling to get this work does this api will be updated for ios9 ?

sokol8 commented 8 years ago

@altagir above is the fix the helped us completely solve the problem.

altagir commented 8 years ago

i am just jumping into this issue, being unfamiliar with this lib and issue.. been struggling to make that work on ios9 i thought simplest fix would be const char fixByte = 0; NSMutableData* fixedModule = [NSMutableData dataWithBytes:&fixByte length:1]; [fixedModule appendData:modulus];

            // previous call
    NSData* prevPublicKeyData = [@[modulus, exponent] berData];
            // suggested fix
    self.publicKeyData = [@[fixedModule, exponent] berData];

    NSData* res = [self encrypt:@"toto"]; // this will crash on ios9

does the code from bugman79 is a replacement of berData function?

altagir commented 8 years ago

solved it finally using bugman79 and
self.publicKeyData = [NSData dataWithBytes:fullKeyBytes length:bytep + [expBits length] ]; but doing so i do not need BasicEncodingRules no more.

lixiayi commented 8 years ago

hi,I'm write my code like this: how do I insert 0 to my modulus?

// Add persistent version of the key to system keychain [publicKey setObject:data forKey:(bridge id)kSecValueData]; [publicKey setObject:(bridge id) kSecAttrKeyClassPublic forKey:(bridge id) kSecAttrKeyClass]; [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(bridge id) kSecReturnPersistentRef];

CFTypeRef persistKey = nil;
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);
if (persistKey != nil){
    CFRelease(persistKey);
}
if ((status != noErr) && (status != errSecDuplicateItem)) {
    return nil;
}

[publicKey removeObjectForKey:(__bridge id)kSecValueData];
[publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
[publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
[publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];

// Now fetch the SecKeyRef version of the key
SecKeyRef keyRef = nil;
status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);
if(status != noErr){
    return nil;
}
return keyRef;

}

BhawnaBhandari24 commented 7 years ago

@bugman79 : Can you provide the sample to generate a 2048 bit key, this code works only for 1024 bit key.

ohrl commented 5 years ago

Probably only need to remove the specific public key header, I fixed the problem on iOS9 this way yesterday.