@@ -93,7 +93,11 @@ const EVP_MD* GetDigestCtxMd(const EVP_MD_CTX* ctx) {
9393}
9494
9595#if NCRYPTO_USE_OPENSSL3_PROVIDER
96+ using ASN1StringPointer = DeleteFnPtr<ASN1_STRING , ASN1_STRING_free>;
9697using OSSLParamBldPointer = DeleteFnPtr<OSSL_PARAM_BLD , OSSL_PARAM_BLD_free>;
98+ using RsaPssParamsPointer = DeleteFnPtr<RSA_PSS_PARAMS , RSA_PSS_PARAMS_free>;
99+ using X509AlgorPointer = DeleteFnPtr<X509_ALGOR , X509_ALGOR_free>;
100+ using X509PubkeyPointer = DeleteFnPtr<X509_PUBKEY , X509_PUBKEY_free>;
97101struct OSSLParamDeleter {
98102 void operator ()(OSSL_PARAM * params) const {
99103 if (params == nullptr ) return ;
@@ -5684,13 +5688,74 @@ bool ReadRsaPssParams(const EVP_PKEY* pkey, Rsa::PssParams* params) {
56845688
56855689 return true ;
56865690}
5691+
5692+ bool SetRsaPssHashAlgorithm (X509_ALGOR ** out, const Digest& digest) {
5693+ if (EVP_MD_is_a (digest.get (), " SHA1" )) return true ;
5694+
5695+ X509AlgorPointer algorithm (X509_ALGOR_new ());
5696+ if (!algorithm) return false ;
5697+ X509_ALGOR_set_md (algorithm.get (), digest.get ());
5698+ *out = algorithm.release ();
5699+ return true ;
5700+ }
5701+
5702+ bool SetRsaPssMaskGenAlgorithm (X509_ALGOR ** out, const Digest& digest) {
5703+ if (EVP_MD_is_a (digest.get (), " SHA1" )) return true ;
5704+
5705+ X509AlgorPointer hash_algorithm (X509_ALGOR_new ());
5706+ if (!hash_algorithm) return false ;
5707+ X509_ALGOR_set_md (hash_algorithm.get (), digest.get ());
5708+
5709+ ASN1StringPointer hash_algorithm_der (ASN1_item_pack (
5710+ hash_algorithm.get (), ASN1_ITEM_rptr (X509_ALGOR ), nullptr ));
5711+ if (!hash_algorithm_der) return false ;
5712+
5713+ X509AlgorPointer algorithm (X509_ALGOR_new ());
5714+ if (!algorithm || X509_ALGOR_set0 (algorithm.get (),
5715+ OBJ_nid2obj (NID_mgf1),
5716+ V_ASN1_SEQUENCE ,
5717+ hash_algorithm_der.get ()) != 1 ) {
5718+ return false ;
5719+ }
5720+ hash_algorithm_der.release ();
5721+ *out = algorithm.release ();
5722+ return true ;
5723+ }
5724+
5725+ ASN1StringPointer EncodeRsaPssParams (const Rsa::PssParams& params) {
5726+ const Digest digest = Digest::FromName (params.digest .data ());
5727+ if (!digest) return {};
5728+
5729+ const Digest mgf1_digest = params.mgf1_digest
5730+ ? Digest::FromName (params.mgf1_digest ->data ())
5731+ : digest;
5732+ if (!mgf1_digest) return {};
5733+
5734+ RsaPssParamsPointer pss (RSA_PSS_PARAMS_new ());
5735+ if (!pss || !SetRsaPssHashAlgorithm (&pss->hashAlgorithm , digest) ||
5736+ !SetRsaPssMaskGenAlgorithm (&pss->maskGenAlgorithm , mgf1_digest)) {
5737+ return {};
5738+ }
5739+
5740+ if (params.salt_length != 20 ) {
5741+ pss->saltLength = ASN1_INTEGER_new ();
5742+ if (pss->saltLength == nullptr ||
5743+ ASN1_INTEGER_set_int64 (pss->saltLength , params.salt_length ) != 1 ) {
5744+ return {};
5745+ }
5746+ }
5747+
5748+ return ASN1StringPointer (
5749+ ASN1_item_pack (pss.get (), ASN1_ITEM_rptr (RSA_PSS_PARAMS ), nullptr ));
5750+ }
56875751} // namespace
56885752
56895753Rsa::Rsa () : rsa_ (false ) {}
56905754
56915755Rsa::Rsa (const EVP_PKEY * pkey) : Rsa () {
56925756 const int type = EVPKeyPointer::id (pkey);
56935757 if (type != EVP_PKEY_RSA && type != EVP_PKEY_RSA_PSS ) return ;
5758+ rsa_pss_ = type == EVP_PKEY_RSA_PSS ;
56945759 if (!GetPKeyBnParam (pkey, OSSL_PKEY_PARAM_RSA_N , &n_) ||
56955760 !GetPKeyBnParam (pkey, OSSL_PKEY_PARAM_RSA_E , &e_)) {
56965761 return ;
@@ -5786,7 +5851,35 @@ BIOPointer Rsa::derPublicKey() const {
57865851 if (!bio) return {};
57875852#if NCRYPTO_USE_OPENSSL3_PROVIDER
57885853 auto pkey = EVPKeyPointer::NewRSA (*this );
5789- if (!pkey || i2d_PUBKEY_bio (bio.get (), pkey.get ()) != 1 ) return {};
5854+ if (!pkey) return {};
5855+ if (!rsa_pss_) {
5856+ if (i2d_PUBKEY_bio (bio.get (), pkey.get ()) != 1 ) return {};
5857+ return bio;
5858+ }
5859+
5860+ X509_PUBKEY * raw_pubkey = nullptr ;
5861+ const int result = X509_PUBKEY_set (&raw_pubkey, pkey.get ());
5862+ X509PubkeyPointer pubkey (raw_pubkey);
5863+ if (result != 1 ) return {};
5864+
5865+ int parameter_type = V_ASN1_UNDEF ;
5866+ ASN1StringPointer parameters;
5867+ if (pss_params_) {
5868+ parameters = EncodeRsaPssParams (*pss_params_);
5869+ if (!parameters) return {};
5870+ parameter_type = V_ASN1_SEQUENCE ;
5871+ }
5872+
5873+ if (X509_PUBKEY_set0_param (pubkey.get (),
5874+ OBJ_nid2obj (NID_rsaEncryption),
5875+ parameter_type,
5876+ parameters.get (),
5877+ nullptr ,
5878+ 0 ) != 1 ) {
5879+ return {};
5880+ }
5881+ parameters.release ();
5882+ if (i2d_X509_PUBKEY_bio (bio.get (), pubkey.get ()) != 1 ) return {};
57905883#else
57915884 if (rsa_ == nullptr || i2d_RSA_PUBKEY_bio (bio.get (), rsa_) != 1 ) return {};
57925885#endif
0 commit comments