Hi Ryan,
To further explain what I’m trying to accomplish .
I’m downloading a .pfx certificate from AmazonWebServices to my phone, then export the certificate to an external token device via bluetooth.
Now, when I’m signing my pdf file - I read / connect to the external token device via bluetooth and parse the certificate from external token device to my app, the certificate comes back as NSMutableData to parse it to an extended OpenSSLSignatureHandler Object class I’ve created with the below methods.
Initially I would pass the .pfx file to the init method, now i have to pass the NSMutableData (cert) from the token device and I’m getting this exception "@throw ([NSException exceptionWithName: @“PDFNet Exception” reason: @“Cannot parse private key.” userInfo: nil]); ".
HEADER FILE
#import <Foundation/Foundation.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pkcs12.h>
#include <openssl/pkcs7.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#import <PDFNet/PDFNetOBJC.h>
#import <PDFNet/PDFViewCtrl.h>
@interface OpenSSLSignatureHandler : PTSignatureHandler {
SHA_CTX m_sha_ctx;
EVP_PKEY *mp_pkey; // private key
X509 *mp_x509; // signing certificate
STACK_OF(X509) *mp_ca; // certificate chain up to the CA
}
- (id) init:(NSString *)p12file password:(NSString )password certder: (NSMutableData) certData ;
- (NSData*) CreateSignature;
- (void) AppendData:(NSData *)data;
- (NSString*) GetName;
- (void) dealloc;
@end
IMPLEMENTATION FILE
#import “OpenSSLSignatureHandler.h”
@implementation OpenSSLSignatureHandler
- (id)init:(NSString *)p12file password:(NSString *)password {
if (self = [super init]) {
// Initialize OpenSSL library
CRYPTO_malloc_init();
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
FILE* fp = fopen([p12file cStringUsingEncoding: NSASCIIStringEncoding], “rb”);
if (fp == NULL)
@throw ([NSException exceptionWithName: @“PDFNet Exception” reason: @“Cannot open private key.” userInfo: nil]);
PKCS12* p12 = d2i_PKCS12_fp(fp, NULL);
fclose(fp);
if (p12 == NULL)
@throw ([NSException exceptionWithName: @“PDFNet Exception” reason: @“Cannot parse private key.” userInfo: nil]);
mp_pkey = NULL;
mp_x509 = NULL;
mp_ca = NULL;
int parseResult = PKCS12_parse(p12, [password cStringUsingEncoding: NSASCIIStringEncoding], &mp_pkey, &mp_x509, &mp_ca);
PKCS12_free(p12);
if (parseResult == 0)
@throw ([NSException exceptionWithName: @“PDFNet Exception” reason: @“Cannot parse private key.” userInfo: nil]);
//initialize sha context
SHA1_Init(&m_sha_ctx);
}
return self;
}
- (NSData *)CreateSignature {
unsigned char sha_buffer[SHA_DIGEST_LENGTH];
memset((void*) sha_buffer, 0, SHA_DIGEST_LENGTH);
SHA1_Final(sha_buffer, &m_sha_ctx);
PKCS7* p7 = PKCS7_new();
PKCS7_set_type(p7, NID_pkcs7_signed);
PKCS7_SIGNER_INFO* p7Si = PKCS7_add_signature(p7, mp_x509, mp_pkey, EVP_sha1());
PKCS7_add_attrib_content_type(p7Si, OBJ_nid2obj(NID_pkcs7_data));
PKCS7_add0_attrib_signing_time(p7Si, NULL);
PKCS7_add1_attrib_digest(p7Si, (const unsigned char*) sha_buffer, SHA_DIGEST_LENGTH);
PKCS7_add_certificate(p7, mp_x509);
int c = 0;
for ( ; c < sk_X509_num(mp_ca); c++) {
X509* cert = sk_X509_value(mp_ca, c);
PKCS7_add_certificate(p7, cert);
}
PKCS7_set_detached(p7, 1);
PKCS7_content_new(p7, NID_pkcs7_data);
PKCS7_SIGNER_INFO_sign(p7Si);
int p7Len = i2d_PKCS7(p7, NULL);
NSMutableData* signature = [NSMutableData data];
unsigned char* p7Buf = (unsigned char*) malloc(p7Len);
if (p7Buf != NULL) {
unsigned char* pP7Buf = p7Buf;
i2d_PKCS7(p7, &pP7Buf);
[signature appendBytes: (const void*) p7Buf length: p7Len];
free(p7Buf);
}
PKCS7_free(p7);
return (signature);
}
-
(void)AppendData:(NSData *)data {
SHA1_Update(&m_sha_ctx, [data bytes], [data length]);
return;
}
-
(NSString *)GetName {
return (@“Adobe.PPKLite”);
}
-
(BOOL)Reset {
SHA1_Init(&m_sha_ctx);
return (YES);
}