0

I'm on R&D to create PKCS 10 CSR, I googled and found very good help on github of this man done, I've done with RSA kSecAttrKeyTypeRSA, Now I want to done same with Eliptic Curve kSecAttrKeyTypeEC but I'm not able to find that need help on this.

EDITED: I tried to convert SCCR.mfrom RSA to ECDSAwithSHA256

  • I get OID of ECDSAWithSHA256 and convert into hex.
  • Change SHA1 with 256 in whole class like CC_SHA256_CTX.
  • Created keypair with kSecAttrKeyTypeEC instead of kSecAttrKeyTypeRSA.

After all this i am getting PEM file in which signature isn't valid. Here below is my whole class.

SCCR.m

/*
This file is part of ios-csr.
Copyright (C) 2013-14 Ales Teska

ios-csr is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

ios-csr is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with ios-csr.  If not, see <http://www.gnu.org/licenses/>.
*/

#import "SCCSR.h"
#include <CommonCrypto/CommonDigest.h>

/*

Certification Request Syntax Specification: http://www.ietf.org/rfc/rfc2986.txt

*/




static uint8_t OBJECT_commonName[5] = {0x06, 0x03, 0x55, 0x04, 0x03};
static uint8_t OBJECT_countryName[5] = {0x06, 0x03, 0x55, 0x04, 0x06};
static uint8_t OBJECT_organizationName[5] = {0x06, 0x03, 0x55, 0x04, 0x0A};
static uint8_t OBJECT_organizationalUnitName[5] = {0x06, 0x03, 0x55, 0x04, 0x0B};

//1.2.840.10045.4.3.2
//\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02
//http://www.oid-info.com/get/1.2.840.10045.4.3.2


static uint8_t OBJECT_ECEncryptionNULL[11] = {0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x00};

static uint8_t SEQUENCE_OBJECT_sha256WithECEncryption[] = {0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x00};

//static uint8_t OBJECT_rsaEncryptionNULL[13] = {0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00};

// See: http://oid-info.com/get/1.2.840.113549.1.1.5
//static uint8_t SEQUENCE_OBJECT_SHA256WithRSAEncryption[] = {0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 1, 1, 5, 0x05, 0x00};

static uint8_t SEQUENCE_tag = 0x30;
static uint8_t SET_tag = 0x31;

///

@implementation SCCSR

@synthesize countryName;
@synthesize organizationName;
@synthesize organizationalUnitName;
@synthesize commonName;
@synthesize subjectDER;

-(SCCSR *)init
{
    self = [super init];
    if (!self) return self;

    countryName = nil;
    organizationName = nil;
    organizationalUnitName = nil;
    commonName = nil;

    subjectDER = nil;

    return self;
}

-(NSData *) build:(NSData *)publicKeyBits privateKey:(SecKeyRef)privateKey
{
    NSMutableData * CertificationRequestInfo = [self buildCertificationRequestInfo:publicKeyBits];

    // Build signature - step 1: SHA256 hash
    CC_SHA256_CTX SHA256;
    CC_SHA256_Init(&SHA256);
    CC_SHA256_Update(&SHA256, [CertificationRequestInfo mutableBytes], (unsigned int)[CertificationRequestInfo length]);
    unsigned char digest[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256_Final(digest, &SHA256);

    // Build signature - step 2: Sign hash
    uint8_t signature[256];
    size_t signature_len = sizeof(signature);
    OSStatus osrc = SecKeyRawSign(
        privateKey,
        kSecPaddingPKCS1SHA256,
        digest, sizeof(digest),
        signature, &signature_len
    );
    assert(osrc == noErr);

    NSMutableData * CertificationRequest = [[NSMutableData alloc] initWithCapacity:1024];
    [CertificationRequest appendData:CertificationRequestInfo];
    [CertificationRequest appendBytes:SEQUENCE_OBJECT_sha256WithECEncryption length:sizeof(SEQUENCE_OBJECT_sha256WithECEncryption)];

    NSMutableData * signdata = [NSMutableData dataWithCapacity:257];
    uint8_t zero = 0;
    [signdata appendBytes:&zero length:1]; // Prepend zero
    [signdata appendBytes:signature length:signature_len];
    [SCCSR appendBITSTRING:signdata into:CertificationRequest];

    [SCCSR enclose:CertificationRequest by:SEQUENCE_tag]; // Enclose into SEQUENCE

    return CertificationRequest;
}


-(NSMutableData *)buildCertificationRequestInfo:(NSData *)publicKeyBits
{
    NSMutableData * CertificationRequestInfo = [[NSMutableData alloc] initWithCapacity:512];

    // Add version
    uint8_t version[3] = {0x02, 0x01, 0x00}; // ASN.1 Representation of integer with value 1
    [CertificationRequestInfo appendBytes:version length:sizeof(version)];


    // Add subject
    NSMutableData * Subject = [[NSMutableData alloc] initWithCapacity:256];
    if (countryName != nil) [SCCSR appendSubjectItem:OBJECT_countryName value:countryName into:Subject];
    if (organizationName != nil) [SCCSR appendSubjectItem:OBJECT_organizationName value:organizationName into:Subject];
    if (organizationalUnitName != nil) [SCCSR appendSubjectItem:OBJECT_organizationalUnitName value:organizationalUnitName into:Subject];
    if (commonName != nil) [SCCSR appendSubjectItem:OBJECT_commonName value:commonName into:Subject];
    [SCCSR enclose:Subject by:SEQUENCE_tag]; // Enclose into SEQUENCE

    subjectDER = [NSData dataWithData:Subject];

    [CertificationRequestInfo appendData:Subject];


    //Add public key info
    NSData * publicKeyInfo = [SCCSR buildPublicKeyInfo:publicKeyBits];
    [CertificationRequestInfo appendData:publicKeyInfo];

    // Add attributes
    uint8_t attributes[2] = {0xA0, 0x00};
    [CertificationRequestInfo appendBytes:attributes length:sizeof(attributes)];


    [SCCSR enclose:CertificationRequestInfo by:SEQUENCE_tag]; // Enclose into SEQUENCE

    return CertificationRequestInfo;
}

/// Utility class methods ...
+(NSData *)buildPublicKeyInfo:(NSData *)publicKeyBits
{
    NSMutableData * publicKeyInfo = [[NSMutableData alloc] initWithCapacity:390];

    [publicKeyInfo appendBytes:OBJECT_ECEncryptionNULL length:sizeof(OBJECT_ECEncryptionNULL)];
    [SCCSR enclose:publicKeyInfo by:SEQUENCE_tag]; // Enclose into SEQUENCE

    NSMutableData * publicKeyASN = [[NSMutableData alloc] initWithCapacity:260];

    NSData * mod = [SCCSR getPublicKeyMod:publicKeyBits];
    char Integer = 0x02; // Integer
    [publicKeyASN appendBytes:&Integer length:1];
    [SCCSR appendDERLength:[mod length] into:publicKeyASN];
    [publicKeyASN appendData:mod];

    NSData * exp = [SCCSR getPublicKeyExp:publicKeyBits];
    [publicKeyASN appendBytes:&Integer length:1];
    [SCCSR appendDERLength:[exp length] into:publicKeyASN];
    [publicKeyASN appendData:exp];

    [SCCSR enclose:publicKeyASN by:SEQUENCE_tag]; // Enclose into ??
    [SCCSR prependByte:0x00 into:publicKeyASN]; // Prepend 0 (?)

    [SCCSR appendBITSTRING:publicKeyASN into:publicKeyInfo];

    [SCCSR enclose:publicKeyInfo by:SEQUENCE_tag]; // Enclose into SEQUENCE

    return publicKeyInfo;
}

+(void)appendSubjectItem:(const uint8_t[5])what value:(NSString *)value into:(NSMutableData *)into
{
    NSMutableData * SubjectItem = [[NSMutableData alloc] initWithCapacity:128];
    [SubjectItem appendBytes:what length:5];
    [SCCSR appendUTF8String:value into:SubjectItem];
    [SCCSR enclose:SubjectItem by:SEQUENCE_tag]; // Enclose into SEQUENCE
    [SCCSR enclose:SubjectItem by:SET_tag]; // Enclose into SET

    [into appendData:SubjectItem];
}

+(void)appendUTF8String:(NSString *)string into:(NSMutableData *)into
{
    char strtype = 0x0C; //UTF8STRING
    [into appendBytes:&strtype length:1];
    [SCCSR appendDERLength:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding] into:into];
    [into appendData:[string dataUsingEncoding:NSUTF8StringEncoding]];
}

+(void)appendDERLength:(size_t)length into:(NSMutableData *)into
{
    assert(length < 0x8000);

    if (length < 128)
    {
        uint8_t d = length;
        [into appendBytes:&d length:1];
    }
    else if (length < 0x100)
    {
        uint8_t d[2] = {0x81, length & 0xFF};
        [into appendBytes:&d length:2];
    }
    else if (length < 0x8000)
    {
        uint8_t d[3] = {0x82, (length & 0xFF00) >> 8, length & 0xFF};
        [into appendBytes:&d length:3];
    }
}

+(void)appendBITSTRING:(NSData *)data into:(NSMutableData *)into
{
    char strtype = 0x03; //BIT STRING
    [into appendBytes:&strtype length:1];
    [SCCSR appendDERLength:[data length] into:into];
    [into appendData:data];
}


+(void)enclose:(NSMutableData *)data by:(uint8_t)by
{
    NSMutableData* newdata = [[NSMutableData alloc]initWithCapacity:[data length]+4];

    [newdata appendBytes:&by length:1];
    [SCCSR appendDERLength:[data length] into:newdata];
    [newdata appendData:data];

    [data setData:newdata];
}

+(void)prependByte:(uint8_t)byte into:(NSMutableData *)into
{
    NSMutableData* newdata = [[NSMutableData alloc]initWithCapacity:[into length]+1];

    [newdata appendBytes:&byte length:1];
    [newdata appendData:into];

    [into setData:newdata];
}

///

// From http://stackoverflow.com/questions/3840005/how-to-find-out-the-modulus-and-exponent-of-rsa-public-key-on-iphone-objective-c

+ (NSData *)getPublicKeyExp:(NSData *)publicKeyBits
{
    int iterator = 0;

    iterator++; // TYPE - bit stream - mod + exp
    [SCCSR derEncodingGetSizeFrom:publicKeyBits at:&iterator]; // Total size

    iterator++; // TYPE - bit stream mod
    int mod_size = [SCCSR derEncodingGetSizeFrom:publicKeyBits at:&iterator];
    iterator += mod_size;

    iterator++; // TYPE - bit stream exp
    int exp_size = [SCCSR derEncodingGetSizeFrom:publicKeyBits at:&iterator];
//  return publicKeyBits;
    return [publicKeyBits subdataWithRange:NSMakeRange(iterator, exp_size)];
}

+(NSData *)getPublicKeyMod:(NSData *)publicKeyBits
{
    int iterator = 0;

    iterator++; // TYPE - bit stream - mod + exp
    [SCCSR derEncodingGetSizeFrom:publicKeyBits at:&iterator]; // Total size

    iterator++; // TYPE - bit stream mod
    int mod_size = [SCCSR derEncodingGetSizeFrom:publicKeyBits at:&iterator];
//    return publicKeyBits;
    //TODO: Changed in Code
    return [publicKeyBits subdataWithRange:NSMakeRange(iterator, mod_size)];
}

+(int)derEncodingGetSizeFrom:(NSData*)buf at:(int*)iterator
{
    const uint8_t* data = [buf bytes];
    int itr = *iterator;
    int num_bytes = 1;
    int ret = 0;

    if (data[itr] > 0x80) {
        num_bytes = data[itr] - 0x80;
        itr++;
    }

    for (int i = 0 ; i < num_bytes; i++) ret = (ret * 0x100) + data[itr + i];

    *iterator = itr + num_bytes;
    return ret;
}

@end

Questions

  • When this OID 1.2.840.113549.1.1.5 convert into hex this become {0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00} which is defined in as static uint8_t OBJECT_rsaEncryptionNULL[13] = {0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00}; then what is SEQUENCE_OBJECT_RSAEncryption which is defined static uint8_t SEQUENCE_OBJECT_RSAEncryption[] = {0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 1, 1, 5, 0x05, 0x00}; ?
  • What will be SEQUENCE_OBJECT_sha256WithECEncryption if it is SHA256withEC

CSR generated from OPENSSL

-----BEGIN CERTIFICATE REQUEST----- MIIC8jCCAdoCAQAwfDELMAkGA1UEBhMCYXMxCzAJBgNVBAgTAnB1MQwwCgYDVQQH EwNsaHIxDDAKBgNVBAoTA3BhazERMA8GA1UECxMIYXNjZXJ0aWExDjAMBgNVBAMT BWFsZWVtMSEwHwYJKoZIhvcNAQkBFhJhbGVlbS5yekBnbWFpbC5jb20wggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzvlvXGw4/YPYbiiCQE2pmqu0x9Ib3 nHk3yMy8ewJIXWOuewVmB7ISBoiAaJ01ON9H/szYUvCGoU5fzz7UFgxCI7biypuy ixo74w7Bd2jRMsH7baZ2W0bhvGoBxN1IMJZHI53J2KF9P5tayLz7OyGQ4Qz8p63A A6Ag3rblIDEBiDr6Xkyxd2atUf4EwB4JcrsLx66RyGDWadXcyO8P39Jg6bgauBMh OW2tq3Y7WsnOnYrYj4m1r9Z1ZFZEIHtHJX9u0qtuHH8yZD/saP5RkUcjIZPHU6Yh gNByRAXCl5YAMTV9yah/AGq6SMwvSRbhX6zgCpI0/eIhvyuzFW/poRlvAgMBAAGg MTAWBgkqhkiG9w0BCQIxCRMHYXNjdGVzdDAXBgkqhkiG9w0BCQcxChMIODc2NTQz MjEwDQYJKoZIhvcNAQELBQADggEBADdv9TOQAV7hEtFsviyp9G08BJgSDBjdP63I Efplt2B1POGvdOKvR1OI5r/qgZZ8E7BTBaFyArUT4+sEdybpmXV9PdO8R7zawD/j 7vmKShYThlPxi/UDrZT8kAwrnBAKgChJ/KMSB6LGdM2wvZKvoN14LFj/KUHtTI97 LYRfhIKFk28yyeSQxK8a3zkPawiTWBYYay9GU13NiKXedps00eV14S7/jAzhL/bk e94LfFybyDcOa2zDWKZOwOGAEStCq4O+7A+t8wrA= -----END CERTIFICATE REQUEST-----

Aleem
  • 3,173
  • 5
  • 33
  • 71
  • @ateska Can we create CSR with Elliptic Curve by using ecdsa-with-SHA256 ad you describe with RSA "https://github.com/ateska/ios-csr"(its quite helpful for me.), I've tried but its keep getting failed. Can you please help me on this how could I do this. – Aleem Nov 24 '16 at 14:04
  • I tried and getting this PEM -----BEGIN CERTIFICATE REQUEST----- MIG+MGkCAQAwSDERMA8GA1UEBgwIUGFraXN0YW4xETAPBgNVBAoMCEFzY2VydGlh MQwwCgYDVQQLDANBU0MxEjAQBgNVBAMMCUQgU2lnbmluZzAYMA0GCSqGSIb3DQEB AQUAAwcAMAQCAAIAoAAGCCqGSM49BAMCA0cAMEQCIHIifMMGs+r+lhN8id2ka5iJ V/ieCtvinsYYGC8UohBjAiA9IkU0k+oUzTeYQnYxSDyPT1h2MRZUmQm/hz+0KjUk Xg== -----END CERTIFICATE REQUEST----- – Aleem Nov 24 '16 at 14:05
  • See http://stackoverflow.com/questions/17277865/is-it-possible-to-generate-certificate-signing-request-csr-using-secuity-frame – Ales Teska Nov 24 '16 at 18:05
  • I'm a bit busy today/this week, sorry for that. Did you try to dump our CSR using `openssl req` tool? – Ales Teska Nov 28 '16 at 18:14
  • @AlesTeska Thanks for your response, Yes I did and create successfully with "sha256WithRSAEncryption"which is defined in my question under *CSR generated from OPENSSL*. I decode this using this site "https://certlogik.com/decoder/" but can't replicate as you did. If you haven't enough time then can you just please convert these "SEQUENCE_OBJECT_sha256WithECEncryption" accordingly with "sha256WithRSAEncryption", I tried same to replicate and also with nopadding but getting signature error. I deadly need your help because I'm stuck here over 3 days. – Aleem Nov 28 '16 at 18:36
  • SEQUENCE_OBJECT_sha256WithECEncryption ... you can grab that sequence from CSR generated by OpenSSL command. The cycle is as follows: you generate a correct CSR file with OpenSSL, open that in hexedit and/or online tool you posted and compare it. Then you know what and how to adjust a iOS CSR generator. – Ales Teska Nov 28 '16 at 19:32
  • @AlesTeska I done that but there is difference. Lets take example of your code "1.2.840.113549.1.1.5" this is you used OID its hex value is "0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05". You used exactly same for BJECT_ECEncryptionNULL and added 0x00 at the end but for SEQUENCE_OBJECT_SHA256WithRSAEncryption you adding some hex value at the start and the end "0x30, 0x0D" and at the end 1,1,5,0x05. Why you are adding ? What should i add for ecdsa ? I tried and copied like you did but i cant get accurate signature so kindly give me response from you precious time? – Aleem Nov 28 '16 at 19:47

0 Answers0