<html><head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head><body bgcolor="#FFFFFF" text="#000000">Hi David,<br>
<br>
I didn't spot the error in your code. But since <span>d2i_RSAPrivateKey()
 fails on the DER data, how about a workaround? If your remaining code 
works fine, you could extract the RSA key from the EVP_PKEY object 
(which you are getting with </span><span>d2i_PrivateKey)</span><span>, 
e.g.<br>
  <br>
   RSA *rsakey;<br>
   rsakey = EVP_PKEY_get1_RSA(privkey);  // this reads EVP_PKEY, best to
 test before to ensure it is RSA<br>
  <br>
   if (RSA_check_key(rsakey)) { printf("RSA key is valid.\n"); }<br>
   else { printf("Error validating RSA key.\n"); }<br>
  <br>
   RSA_print_fp(stdout, rsakey, 3);<br>
   ...<br>
  <br>
Alternatively, building a test case around </span><span><span>d2i_RSAPrivateKey()
 to see if the DER format is valid, e.g. converting the PEM key into DER
 using the OpenSSL commandline, and binary-compare with the programs DER
 data. <br>
  <br>
openssl rsa -inform PEM -in test-key.pem -outform DER -out key.bin<br>
  <br>
Best Wishes,<br>
Frank</span> <br>
</span>
<blockquote style="border: 0px none;" 
cite="mid:76D28034-71CE-48B1-A78F-05D099E095BD@akamai.com" type="cite">
  <div style="margin:30px 25px 10px 25px;" class="__pbConvHr"><div 
style="display:table;width:100%;border-top:1px solid 
#EDEEF0;padding-top:5px">       <div 
style="display:table-cell;vertical-align:middle;padding-right:6px;"><img
 photoaddress="dlobron@akamai.com" photoname="David Lobron" 
src="cid:part1.06050607.07040406@frank4dd.com" 
name="compose-unknown-contact.jpg" height="25px" width="25px"></div>   <div
 
style="display:table-cell;white-space:nowrap;vertical-align:middle;width:100%">
        <a moz-do-not-send="true" href="mailto:dlobron@akamai.com" 
style="color:#737F92 
!important;padding-right:6px;font-weight:bold;text-decoration:none 
!important;">David Lobron</a></div>   <div 
style="display:table-cell;white-space:nowrap;vertical-align:middle;">   
  <font color="#9FA2A5"><span style="padding-left:6px">Monday, October 
12, 2015 11:34 PM</span></font></div></div></div>
  <div style="color:#888888;margin-left:24px;margin-right:24px;" 
__pbrmquotes="true" class="__pbConvBody"><div><!----><br>Thanks very 
much, Frank.  My code reads the PEM file, base64-decodes it, and passes 
the resulting DER value to d2i_RSAPrivateKey.  I verified that I can 
extract the private key with d2i_PrivateKey from the DER formatted data,
 and I can call SSL_CTX_use_PrivateKey with it on my SSL context without
 a problem.  It's only when I call d2i_RSAPrivateKey I encounter a 
problem.  I have included the code below, with annotations (it's in 
Objective-C).  <br><br>I've got custom classes for X509Certificate and 
X509PrivateKey.  I use them like this:<br><br>X509Certificate *cert = 
[X509Certificate certificateWithPemEncodedFile:certFile];<br>X509PrivateKey
 *privKey = [X509PrivateKey privateKeyWithPemEncodedFile:keyFile];<br>[cert
 validateWithPrivateKey:privKey];<br>[privKey validate];<br><br>That 
last call to [privKey validate] is where things fail currently.  The 
validateWithPrivateKey method works fine, and it looks like this:<br><br>-
 (void)validateWithPrivateKey:(X509PrivateKey *)key<br>{<br>    SSL_CTX 
*sslContext;<br>    <br>    [self validate];<br>    sslContext = 
SSL_CTX_new(TLSv1_server_method());<br>    NS_DURING {<br>        NSData
 *d = [key der];<br>        const unsigned char *p = (const unsigned 
char *)[d bytes];<br>        EVP_PKEY *pkey = 
d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p, [d length]);<br>        if 
(!sslContext)<br>            [NSException 
raise:X509CertificateExcInternalError format:@"SSL_CTX_new failed: %@", 
sslErrorString()];<br>        if (SSL_CTX_use_certificate(sslContext, 
_x) != 1)<br>            [NSException 
raise:X509CertificateExcInvalidCertificate 
format:@"SSL_CTX_use_certificate failed: %@", sslErrorString()];<br>    
    if (SSL_CTX_use_PrivateKey(sslContext, pkey) != 1)<br>            
[NSException raise:X509CertificateExcInvalidPrivateKey 
format:@"SSL_CTX_use_PrivateKey_ASN1 failed: %@", sslErrorString()];<br>
        SSL_CTX_free(sslContext);<br>    } NS_HANDLER {<br>        if 
(sslContext)<br>            SSL_CTX_free(sslContext);<br>        
[localException raise];<br>    } NS_ENDHANDLER<br>}<br><br>(That initial
 call to "self validate" simply validates the cert object's SSL_CTX). <br><br>I
 initialize my private key object as follows:<br><br>- 
(id)initWithPemEncodedFile:(NSString *)path<br>{<br>    NSData *d = nil;<br>
    NS_DURING {<br>        NSString *s;<br>        NSArray *inputLines;<br>
        <br>        // read the file<br>        s = [NSString 
stringWithContentsOfFile:path];<br>        if (s == nil || [s length] ==
 0)<br>            [NSException raise:X509CertificateExcParameterError 
format:@"File %@ is empty or cannot be read", path];<br>        
inputLines = [s componentsSeparatedByString:@"\n"];<br>        d = 
[X509Certificate decodePemFragmentFromLines:inputLines 
withBoundaryPhrases:[NSArray arrayWithObjects:@"PRIVATE KEY", @"RSA 
PRIVATE KEY", nil]];<br>    } NS_HANDLER {<br>        [self release];<br>
        [localException raise];<br>    } NS_ENDHANDLER<br>    return 
[self initWithDer:d];<br><br>}<br><br>The decodePemFragmentFromLines 
method looks like this:<br><br>// Extract part of a PEM-encoded message,
 base64-decode it, and return an NSData object<br>+ (NSData 
*)decodePemFragmentFromLines:(NSArray *)inputLines 
withBoundaryPhrases:(NSArray *)boundaryPhrases<br>{<br>    NSEnumerator 
*e = [inputLines objectEnumerator];<br>    NSMutableString *b64 = 
[NSMutableString string];<br>    NSString *s;<br>    NSString 
*boundaryPhrase = nil;<br>    NSString *startBoundary = nil;<br>    
NSString *endBoundary = nil;<br>    <br>    while ((s = [e nextObject]) 
!= nil) {<br>        NSEnumerator *e = [boundaryPhrases 
objectEnumerator];<br>        while ((boundaryPhrase = [e nextObject]) 
!= nil) {<br>            startBoundary = [NSString 
stringWithFormat:@"-----BEGIN %@-----", boundaryPhrase];<br>            
if ([s isEqualToString:startBoundary]) {<br>                endBoundary =
 [NSString stringWithFormat:@"-----END %@-----", boundaryPhrase];<br>   
             break;<br>            }<br>        }<br>        if 
(endBoundary != nil)<br>            break;<br>    }<br>    if (s == nil)<br>
        [NSException raise:X509CertificateExcParameterError format:@"Start 
boundary \"%@\" not found", startBoundary];<br>    while ((s = [e 
nextObject]) != nil) {<br>        if ([s isEqualToString:endBoundary])<br>      
break;<br>        [b64 appendString:s];<br>    }<br>    if (s == nil)<br>       
[NSException raise:X509CertificateExcParameterError format:@"End 
boundary \"%@\" not found", endBoundary];<br>    return 
base64Decode(b64);<br>}<br><br>The initWithDer method is simply:<br><br>-
 (id)initWithDer:(NSData *)der<br>{<br>    if ((self = [super init]) != 
nil) {<br>        _der = [der copy];<br>    }<br>    return self;<br>}<br><br>All
 of the above works as expected, but when I call d2i_RSAPrivateKey on 
the _der object, it fails.  Here is the code that throws the exception:<br><br>//
 validate; throws exception if key invalid<br>- (void)validate<br>{<br> 
   const unsigned char *p = (unsigned char *)[_der bytes];<br>    RSA *r
 = d2i_RSAPrivateKey(0, &p, [_der length]);<br>    int n;<br>    if 
(r == 0)<br>      [NSException raise:X509CertificateExcInvalidPrivateKey 
format:@"cannot decode RSA private key"];<br>    NS_DURING {<br>  switch 
(n = RSA_check_key(r)) {<br>          case 1:             // ok<br>         break;<br>            
default:<br>              [NSException raise:X509CertificateExcInvalidPrivateKey 
format:@"RSA_check_key() returned %d", n];<br>  }<br>    } NS_HANDLER {<br>
        RSA_free(r);<br>  [localException raise];<br>    } NS_ENDHANDLER<br>    
RSA_free(r);<br><br>}<br><br>Thanks for any help you can give here!<br><br>--David<br><br><br></div><div>_______________________________________________<br>openssl-users
 mailing list<br>To unsubscribe: 
<a class="moz-txt-link-freetext" href="https://mta.openssl.org/mailman/listinfo/openssl-users">https://mta.openssl.org/mailman/listinfo/openssl-users</a><br></div></div>
</blockquote>
<br>
<div class="moz-signature">-- <br>
<div>Sent with <a href="http://www.getpostbox.com"><span style="color: 
rgb(51, 102, 153);">Postbox</span></a></div></div>
</body></html>