//////////////////////////////////////////////////////////////////////////////// // Copyright 2016 Google LLC. // // This software is licensed under the terms defined in the Widevine Master // License Agreement. For a copy of this agreement, please contact // widevine-licensing@google.com. //////////////////////////////////////////////////////////////////////////////// // // Description: // RSA utility functions for serializing and deserializing RSA keys, // encryption, and signing. #ifndef COMMON_RSA_UTIL_H_ #define COMMON_RSA_UTIL_H_ #include #include "openssl/rsa.h" namespace widevine { namespace rsa_util { // Serialize RSA private key into DER encoded PKCS#1 RSAPrivateKey. // - private_key is the RSA key to be serialized, which must not be NULL. // - serialized_private_key is a pointer to the std::string to hold the serialized // PKCS#1 RSAPrivateKey object. Caller retains ownership of the string. This // parameter must not be NULL. // Returns true if successful, false otherwise. bool SerializeRsaPrivateKey(const RSA* private_key, std::string* serialized_private_key); // Deserialize RSA private key from DER encoded PKCS#1 RSAPrivateKey. // - serialized_private_key is the DER-encoded PKCS#1 RSAPrivateKey to be // deserialized. // - private_key is a pointer to an RSA structure pointer to point to a newly // allocated RSA structure. Caller assumes ownership of the new RSA pointer, // which is not allocated if the method fails. This parameter must not be // NULL. // Returns true if successful, false otherwise. bool DeserializeRsaPrivateKey(const std::string& serialized_private_key, RSA** private_key); // Serialize RSA key into DER encoded PKCS#1 RSAPublicKey. // - public_key is the RSA key to be serialized, which must not be NULL. // - serialized_public_key is a pointer to the std::string to hold the serialized // PKCS#1 RSAPublicKey object. Caller retains ownership of the string. This // parameter must not be NULL. // Returns true if successful, false otherwise. bool SerializeRsaPublicKey(const RSA* public_key, std::string* serialized_public_key); // Deserialize RSA public key from DER encoded PKCS#1 RSAPublicKey. // - serialized_public_key is the DER-encoded PKCS#1 RSAPublicKey to be // deserialized. // - public_key is a pointer to an RSA structure pointer to point to a newly // allocated RSA structure. Caller assumes ownership of the new RSA pointer, // which is not allocated if the method fails. This parameter must not be // NULL. // Returns true if successful, false otherwise. bool DeserializeRsaPublicKey(const std::string& serialized_public_key, RSA** public_key); // Serialize RSA private key into DER encoded PKCS#8 PrivateKeyInfo. // - private_key is the RSA key to be serialized, which must not be NULL. // - serialized_private_key is a pointer to the std::string to hold the serialized // PKCS#8 PrivateKeyInfo object. Caller retains ownership of the string. This // parameter must not be NULL. // Returns true if successful, false otherwise. bool SerializePrivateKeyInfo(const RSA* private_key, std::string* serialized_private_key); // Deserialize RSA private key from DER encoded PKCS#8 PrivateKeyInfo. // - serialized_private_key is the DER-encoded PKCS#8 PrivateKeyInfo to be // deserialized. // - private_key is a pointer to an RSA structure pointer to point to a newly // allocated RSA structure. Caller assumes ownership of the new RSA pointer, // which is not allocated if the method fails. This parameter must not be // NULL. // Returns true if successful, false otherwise. bool DeserializePrivateKeyInfo(const std::string& serialized_private_key, RSA** private_key); // Convert DER-encoded PKCS#1 RSAPrivateKey to DER-encoded PKCS#8 // PrivateKeyInfo. // - rsa_private_key is the PKCS#1 RSAPrivateKey to be converted. // - private_key_info is a pointer to std::string to hold the PKCS#8 PrivateKeyInfo. // The caller retains ownership of this parameter, which must not be NULL. // Returns true if successful, false otherwise. bool RsaPrivateKeyToPrivateKeyInfo(const std::string& rsa_private_key, std::string* private_key_info); // Convert DER-encoded PKCS#8 PrivateKeyInfo to DER-encoded PKCS#1 // RSAPrivateKey. // - private_key_info is the PKCS#8 PrivateKeyInfo to be converted. // - rsa_private_key is a pointer to std::string to hold the PKCS#1 RSAPrivateKey. // The caller retains ownership of this parameter, which must not be NULL. // Returns true if successful, false otherwise. bool PrivateKeyInfoToRsaPrivateKey(const std::string& private_key_info, std::string* rsa_private_key); // Serialize RSA private key into DER encoded PKCS#8 EncryptedPrivateKeyInfo. // - private_key is the RSA key to be serialized, which must not be NULL. // - passphrase is the password to use for PKCS#5 v2.0 3DES encryption. // - serialized_private_key is a pointer to the std::string to hold the serialized // PKCS#8 EncryptedPrivateKeyInfo object. Caller retains ownership of the // string. This parameter must not be NULL. // Returns true if successful, false otherwise. bool SerializeEncryptedPrivateKeyInfo(const RSA* private_key, const std::string& passphrase, std::string* serialized_private_key); // Deserialize RSA private key from DER encoded PKCS#8 EncryptedPrivateKeyInfo. // - serialized_private_key is the DER-encoded PKCS#8 EncryptedPrivateKeyInfo to // be deserialized. // - passphrase is the password to use for key decryption. // - private_key is a pointer to an RSA structure pointer to point to a newly // allocated RSA structure. Caller assumes ownership of the new RSA pointer, // which is not allocated if the method fails. This parameter must not be // NULL. // Returns true if successful, false otherwise. bool DeserializeEncryptedPrivateKeyInfo(const std::string& serialized_private_key, const std::string& passphrase, RSA** private_key); // Convert DER-encoded PKCS#1 RSAPrivateKey to DER-encoded PKCS#8 // EncryptedPrivateKeyInfo. // - rsa_private_key is the PKCS#1 RSAPrivateKey to be converted. // - passphrase is the password to use for PKCS#5 v2.1 AES-256-CBC encryption. // - private_key_info is a pointer to std::string to hold the PKCS#8 // EncryptedPrivateKeyInfo. // The caller retains ownership of this parameter, which must not be NULL. // Returns true if successful, false otherwise. bool RsaPrivateKeyToEncryptedPrivateKeyInfo(const std::string& rsa_private_key, const std::string& passphrase, std::string* private_key_info); // Convert DER-encoded PKCS#8 EncryptedPrivateKeyInfo to DER-encoded PKCS#1 // RSAPrivateKey. // - private_key_info is the PKCS#8 EncryptedPrivateKeyInfo to be converted. // - passphrase is the password to use for key decryption. // - rsa_private_key is a pointer to std::string to hold the PKCS#1 RSAPrivateKey. // The caller retains ownership of this parameter, which must not be NULL. // Returns true if successful, false otherwise. bool EncryptedPrivateKeyInfoToRsaPrivateKey(const std::string& private_key_info, const std::string& passphrase, std::string* rsa_private_key); // This method changes |rsa| to use the more common, but not FIPS 186-4 // compliant, computation for the RSA private exponent (d). This used to be the // form produced by the BoringSSL method RSA_generate_key. This changed in this // CL: https://boringssl-review.googlesource.com/c/boringssl/+/15944 // // This method is used to produce a "backward-compatible" version. Some vendor // RSA implementations do not handle the new computation properly. // // - rsa is the openssl RSA structure. Must not be null. Caller retains // ownership. // // Returns true if the key was successfully updated, false otherwise. bool ConvertToEulerTotient(RSA* rsa); // This is wrapper to the other SwitchToEulerTotient that supports deserializing // and serializing from and to a DER encoded PKCS#1 RSAPrivateKey. // // - private_key is the DER-encoded PKCS#1 RSAPrivateKey to be // deserialized and converted. // - euler_private_key is a pointer to the std::string to hold the converted and // serialized PKCS#1 RSAPrivateKey object. Caller retains ownership of the // string. This parameter must not be NULL. // Returns true if the key was successfully updated, false otherwise. bool ConvertToEulerTotient(const std::string& private_key, std::string* euler_private_key); // This method changes |rsa| to use the FIPS 186-4 compliant computation for d. // This uses the Carmichael totient. This is equivalent to the way the key // is generated in BoringSSL as of this change: // https://boringssl-review.googlesource.com/c/boringssl/+/15944 // // This method is mostly used for testing. It allows tests to convert back and // forth between forms and verify the output. // // Returns true if the key can be successfully updated, false otherwise. bool ConvertToCarmichaelTotient(RSA* rsa); // This is wrapper to the other SwitchToCarmichaelTotient that supports // deserializing and serializing from and to a DER encoded PKCS#1 RSAPrivateKey. // // - private_key is the DER-encoded PKCS#1 RSAPrivateKey to be // deserialized and converted. // - carmichael_private_key is a pointer to the std::string to hold the converted and // serialized PKCS#1 RSAPrivateKey object. Caller retains ownership of the // string. This parameter must not be NULL. // Returns true if the key was successfully updated, false otherwise. bool ConvertToCarmichaelTotient(const std::string& private_key, std::string* carmichael_private_key); } // namespace rsa_util } // namespace widevine #endif // COMMON_RSA_UTIL_H_