Translate PEM to DER on Windows CE 3

2019-07-02 15:59发布

问题:

I have a RSA public key crypto wrapper which works quite well in desktop Windows and Windows Embedded/POSReady. I need to port this system to both Windows CE 5 and Windows CE 3. In part of this system, I allow developers to import various crypto objects, such as certificates and keys, in several encodings. The most commonly used encoding is Base64 encoded PEM. On most versions of Windows, it is easy to convert encodings to the binary (DER) format that Windows needs for CryptDecodeObjectEx calls:

bool MyClass::externalToBinary( const DATA_BLOB &in, DATA_BLOB &outDER )
{
    DWORD flags;

    // This call determines the format and how much memory is needed in outDER
    if ( ::CryptStringToBinaryA( reinterpret_cast<char *>(in.pbData), in.cbData, CRYPT_STRING_ANY,     NULL, &outDER.cbData, NULL, &flags ) == false &&
         ::CryptStringToBinaryA( reinterpret_cast<char *>(in.pbData), in.cbData, CRYPT_STRING_HEX_ANY, NULL, &outDER.cbData, NULL, &flags ) == false )
    {
        // Log errors here using ::GetLastError();
        return false;
    }

    if ( ( outDER.pbData = new unsigned char[outDER.cbData] ) == NULL )
    {
        // Log errors here using ::GetLastError();
        return false;
    }
    return ( ::CryptStringToBinaryA( reinterpret_cast<char *>(in.pbData), in.cbData, flags, outDER.pbData, &outDER.cbData, NULL, NULL ) != FALSE );
} // end externalToBinary

Unfortunately, CryptStringToBinary doesn't exist in Windows CE 3's version of CryptoAPI. While I can do away with support for less popular encodings (such as hex), I really don't want to remove support for PEM encoding in the CE 3 version of the API.

Does anyone have a CryptStringToBinary alternative that would work on Windows CE 3? The developers using this API don't currently have OpenSSL as a dependency, so I would prefer not to add it just for this.

回答1:

Well - PEM is simply base64 encoded DER. So if this is the only place you need to convert; I'd just forego the API niceties; strip off any empty line or line starting with a '-'; and base64 decode the anything in between. The result is the DER you're after. WindowsCE3 has a Encode/Decodeter type for Base64; If for some reason you do not/cannot want to use that - How do I base64 encode (decode) in C? or http://www.adp-gmbh.ch/cpp/common/base64.html are fairly trivial 'raw' versions.