I am using Open SSL for RSA key pair generation and signing token with SHA1 Algorithm. Key pair generation was successfully done using OpenSSL and i got "PEM" certificate as result.
To proceed with signing process, i need DER formatted Private Key. If anyone knows, please share the code to convert PEM to DER certificates using openssl. I tried with terminal and it's working fine. But, i need the programmatic approach for this.
Following is my code to generate PEM certificate:
-(void)generateCertificate
{
RSA *rsaKeyPair = NULL;
rsaKeyPair = RSA_new();
BIGNUM *e = BN_new();
BN_set_word(e, 65537);
//Generating KeyPair
RSA_generate_key_ex(rsaKeyPair, 1024, e, NULL);
int keylen, keylenPub;
char *pem_key, *pem_pub_key;
/* To get the C-string PEM form: */
BIO *bio = BIO_new(BIO_s_mem());
BIO *bioPubKey = BIO_new(BIO_s_mem());
//Writing RSA Private and Public Keys
PEM_write_bio_RSAPrivateKey(bio, rsaKeyPair, NULL, NULL, 0, NULL, NULL);
PEM_write_bio_RSAPublicKey(bioPubKey, rsaKeyPair);
keylen = BIO_pending(bio);
pem_key = calloc(keylen+1, 1); /* Null-terminate */
BIO_read(bio, pem_key, keylen);
//Reading RSA Public Key Bio
keylenPub = BIO_pending(bioPubKey);
pem_pub_key = calloc(keylenPub+1, 1); /* Null-terminate */
BIO_read(bioPubKey, pem_pub_key, keylenPub);
NSString *strData = [NSString stringWithUTF8String:pem_key];
[strData writeToFile:[self privateKeyPath] atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSString *strPubData = [NSString stringWithUTF8String:pem_pub_key];
[strPubData writeToFile:[self publicKeyPath] atomically:YES encoding:NSUTF8StringEncoding error:nil];
BIO_free_all(bio);
RSA_free(rsaKeyPair);
}
And:
// Documents directory path
-(NSString *)privateKeyPath
{
NSString *documentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
return [documentsFolder stringByAppendingPathComponent:@"rsaprivkey.pem"];
}
And:
-(NSString *)publicKeyPath
{
NSString *documentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
return [documentsFolder stringByAppendingPathComponent:@"rsapubkey.pem"];
}
And:
-(NSString *)derPrivateKeyPath
{
NSString *documentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
return [documentsFolder stringByAppendingPathComponent:@"rsaprivateKey.der"];
}
And:
#pragma mark - Signing section
-(NSData *)generateSignatureWithdataToSign :(NSData*)signableData
{
BIO *in = BIO_new_file([[self derPrivateKeyPath] cStringUsingEncoding:NSUTF8StringEncoding], "rb");
PKCS8_PRIV_KEY_INFO *p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in,NULL);
EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf);
NSLog(@"%i", p8inf->broken);
PKCS8_PRIV_KEY_INFO_free(p8inf);
BIO_free(in);
uint8_t * cipherBuffer = NULL;
// Calculate the buffer sizes.
unsigned int cipherBufferSize = RSA_size(pkey->pkey.rsa);
unsigned int signatureLength;
// Allocate some buffer space. I don't trust calloc.
cipherBuffer = malloc(cipherBufferSize);
memset((void *)cipherBuffer, 0x0, cipherBufferSize);
unsigned char *openSSLHash = SHA1(signableData.bytes, signableData.length, NULL);
int success = RSA_sign(NID_sha1, openSSLHash, 20, cipherBuffer, &signatureLength, pkey->pkey.rsa); //pkey->pkey.rsa
if (success) NSLog(@"WIN");
NSData *signatureData = [NSData dataWithBytes:(const void*)cipherBuffer length:signatureLength];
EVP_PKEY_free(pkey);
return signatureData;
}
Note: I want to get DER certificate from "rsaprivkey.pem" and write that DER to "rsaprivateKey.der" .. After that, i need to implement the signing process as coded above by using "rsaprivateKey.der" certificate...