21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

if (!(buf = next = (unsigned char *)malloc(*len))) return 0;<br />

i2d_RSAPublicKey(rsa, &next); /* If we use buf here, return buf; becomes wrong */<br />

return buf;<br />

}<br />

For each basic function in the i2d API, there are two additional functions—implemented<br />

as macros—that output to a FILE object or an OpenSSL BIO object, which is<br />

the library’s generic IO abstraction. * The name of the base function is suffixed with _fp<br />

or _bio as appropriate, and the second argument changes to a FILE or a BIO pointer as<br />

appropriate.<br />

The d2i API converts DER-encoded data to an internal OpenSSLrepresentation. The<br />

functions in this API take three arguments. The first is a pointer to a pointer to the<br />

appropriate OpenSSLobject (for example, an RSA ** instead of the expected RSA *).<br />

The second is a pointer to a pointer to the buffer storing the representation (i.e., a<br />

char ** instead of a char *). The third is the input length of the buffer (a long int).<br />

The first two arguments are pointers to pointers because OpenSSL“advances” your<br />

pointer just as it does in the i2d API.<br />

The return value is a pointer to the object written. However, if the object cannot be<br />

decoded successfully (i.e., if there’s an error in the encoded data stream), a NULL<br />

value will be returned. The first argument may be a NULL value, in which case an<br />

object of the appropriate type is allocated and returned.<br />

Here’s an example of converting an RSA public key from DER format to OpenSSL’s<br />

internal representation:<br />

#include <br />

/* Note that the pointer to the buffer gets copied in. Therefore, when<br />

* d2i_… changes its value, those changes aren't reflected in the caller's copy<br />

* of the pointer.<br />

*/<br />

RSA *DER_decode_RSA_public(unsigned char *buf, long len) {<br />

return d2i_RSAPublicKey(0, &buf, len);<br />

}<br />

As with the i2d interface, all of the functions have macros that allow you to pass in a<br />

FILE or an OpenSSL BIO object, this time so that you may use one as the input<br />

source. Those macros take only two arguments, where the base function takes three.<br />

The first argument is the BIO or FILE pointer from which to read. The second argument<br />

is a pointer to a pointer to the output object (for example, an RSA **). Again,<br />

you can pass in a NULL value for this argument. The len argument is omitted; the<br />

library figures it out for itself. It could have figured it out for itself in the base API,<br />

* There are three exceptions to this rule, having to do with the OpenSSLEVP interface. We don’t discuss (or<br />

even list) the functions here, because we don’t cover the OpenSSLEVP interface (it’s not a very good abstraction<br />

of anything in our opinion). If you do want to look at this interface, it’s covered in the book Network<br />

Security with OpenSSL.<br />

354 | Chapter 7: Public Key Cryptography<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!