1238384Sjkim/* crypto/rsa/rsa_ameth.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4296341Sdelphij * 2006. 5238384Sjkim */ 6238384Sjkim/* ==================================================================== 7238384Sjkim * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 8238384Sjkim * 9238384Sjkim * Redistribution and use in source and binary forms, with or without 10238384Sjkim * modification, are permitted provided that the following conditions 11238384Sjkim * are met: 12238384Sjkim * 13238384Sjkim * 1. Redistributions of source code must retain the above copyright 14296341Sdelphij * notice, this list of conditions and the following disclaimer. 15238384Sjkim * 16238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 17238384Sjkim * notice, this list of conditions and the following disclaimer in 18238384Sjkim * the documentation and/or other materials provided with the 19238384Sjkim * distribution. 20238384Sjkim * 21238384Sjkim * 3. All advertising materials mentioning features or use of this 22238384Sjkim * software must display the following acknowledgment: 23238384Sjkim * "This product includes software developed by the OpenSSL Project 24238384Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25238384Sjkim * 26238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27238384Sjkim * endorse or promote products derived from this software without 28238384Sjkim * prior written permission. For written permission, please contact 29238384Sjkim * licensing@OpenSSL.org. 30238384Sjkim * 31238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 32238384Sjkim * nor may "OpenSSL" appear in their names without prior written 33238384Sjkim * permission of the OpenSSL Project. 34238384Sjkim * 35238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 36238384Sjkim * acknowledgment: 37238384Sjkim * "This product includes software developed by the OpenSSL Project 38238384Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39238384Sjkim * 40238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 52238384Sjkim * ==================================================================== 53238384Sjkim * 54238384Sjkim * This product includes cryptographic software written by Eric Young 55238384Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 56238384Sjkim * Hudson (tjh@cryptsoft.com). 57238384Sjkim * 58238384Sjkim */ 59238384Sjkim 60238384Sjkim#include <stdio.h> 61238384Sjkim#include "cryptlib.h" 62238384Sjkim#include <openssl/asn1t.h> 63238384Sjkim#include <openssl/x509.h> 64238384Sjkim#include <openssl/rsa.h> 65238384Sjkim#include <openssl/bn.h> 66238384Sjkim#ifndef OPENSSL_NO_CMS 67296341Sdelphij# include <openssl/cms.h> 68238384Sjkim#endif 69238384Sjkim#include "asn1_locl.h" 70238384Sjkim 71238384Sjkimstatic int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 72296341Sdelphij{ 73296341Sdelphij unsigned char *penc = NULL; 74296341Sdelphij int penclen; 75296341Sdelphij penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); 76296341Sdelphij if (penclen <= 0) 77296341Sdelphij return 0; 78296341Sdelphij if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), 79296341Sdelphij V_ASN1_NULL, NULL, penc, penclen)) 80296341Sdelphij return 1; 81238384Sjkim 82296341Sdelphij OPENSSL_free(penc); 83296341Sdelphij return 0; 84296341Sdelphij} 85238384Sjkim 86238384Sjkimstatic int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) 87296341Sdelphij{ 88296341Sdelphij const unsigned char *p; 89296341Sdelphij int pklen; 90296341Sdelphij RSA *rsa = NULL; 91296341Sdelphij if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) 92296341Sdelphij return 0; 93296341Sdelphij if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) { 94296341Sdelphij RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); 95296341Sdelphij return 0; 96296341Sdelphij } 97296341Sdelphij EVP_PKEY_assign_RSA(pkey, rsa); 98296341Sdelphij return 1; 99296341Sdelphij} 100238384Sjkim 101238384Sjkimstatic int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 102296341Sdelphij{ 103296341Sdelphij if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 104296341Sdelphij || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) 105296341Sdelphij return 0; 106296341Sdelphij return 1; 107296341Sdelphij} 108238384Sjkim 109238384Sjkimstatic int old_rsa_priv_decode(EVP_PKEY *pkey, 110296341Sdelphij const unsigned char **pder, int derlen) 111296341Sdelphij{ 112296341Sdelphij RSA *rsa; 113296341Sdelphij if (!(rsa = d2i_RSAPrivateKey(NULL, pder, derlen))) { 114296341Sdelphij RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); 115296341Sdelphij return 0; 116296341Sdelphij } 117296341Sdelphij EVP_PKEY_assign_RSA(pkey, rsa); 118296341Sdelphij return 1; 119296341Sdelphij} 120238384Sjkim 121238384Sjkimstatic int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) 122296341Sdelphij{ 123296341Sdelphij return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); 124296341Sdelphij} 125238384Sjkim 126238384Sjkimstatic int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 127296341Sdelphij{ 128296341Sdelphij unsigned char *rk = NULL; 129296341Sdelphij int rklen; 130296341Sdelphij rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); 131238384Sjkim 132296341Sdelphij if (rklen <= 0) { 133296341Sdelphij RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 134296341Sdelphij return 0; 135296341Sdelphij } 136238384Sjkim 137296341Sdelphij if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0, 138296341Sdelphij V_ASN1_NULL, NULL, rk, rklen)) { 139296341Sdelphij RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 140296341Sdelphij return 0; 141296341Sdelphij } 142238384Sjkim 143296341Sdelphij return 1; 144296341Sdelphij} 145238384Sjkim 146238384Sjkimstatic int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) 147296341Sdelphij{ 148296341Sdelphij const unsigned char *p; 149296341Sdelphij int pklen; 150296341Sdelphij if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) 151296341Sdelphij return 0; 152296341Sdelphij return old_rsa_priv_decode(pkey, &p, pklen); 153296341Sdelphij} 154238384Sjkim 155238384Sjkimstatic int int_rsa_size(const EVP_PKEY *pkey) 156296341Sdelphij{ 157296341Sdelphij return RSA_size(pkey->pkey.rsa); 158296341Sdelphij} 159238384Sjkim 160238384Sjkimstatic int rsa_bits(const EVP_PKEY *pkey) 161296341Sdelphij{ 162296341Sdelphij return BN_num_bits(pkey->pkey.rsa->n); 163296341Sdelphij} 164238384Sjkim 165238384Sjkimstatic void int_rsa_free(EVP_PKEY *pkey) 166296341Sdelphij{ 167296341Sdelphij RSA_free(pkey->pkey.rsa); 168296341Sdelphij} 169238384Sjkim 170238384Sjkimstatic void update_buflen(const BIGNUM *b, size_t *pbuflen) 171296341Sdelphij{ 172296341Sdelphij size_t i; 173296341Sdelphij if (!b) 174296341Sdelphij return; 175296341Sdelphij if (*pbuflen < (i = (size_t)BN_num_bytes(b))) 176296341Sdelphij *pbuflen = i; 177296341Sdelphij} 178238384Sjkim 179238384Sjkimstatic int do_rsa_print(BIO *bp, const RSA *x, int off, int priv) 180296341Sdelphij{ 181296341Sdelphij char *str; 182296341Sdelphij const char *s; 183296341Sdelphij unsigned char *m = NULL; 184296341Sdelphij int ret = 0, mod_len = 0; 185296341Sdelphij size_t buf_len = 0; 186238384Sjkim 187296341Sdelphij update_buflen(x->n, &buf_len); 188296341Sdelphij update_buflen(x->e, &buf_len); 189238384Sjkim 190296341Sdelphij if (priv) { 191296341Sdelphij update_buflen(x->d, &buf_len); 192296341Sdelphij update_buflen(x->p, &buf_len); 193296341Sdelphij update_buflen(x->q, &buf_len); 194296341Sdelphij update_buflen(x->dmp1, &buf_len); 195296341Sdelphij update_buflen(x->dmq1, &buf_len); 196296341Sdelphij update_buflen(x->iqmp, &buf_len); 197296341Sdelphij } 198238384Sjkim 199296341Sdelphij m = (unsigned char *)OPENSSL_malloc(buf_len + 10); 200296341Sdelphij if (m == NULL) { 201296341Sdelphij RSAerr(RSA_F_DO_RSA_PRINT, ERR_R_MALLOC_FAILURE); 202296341Sdelphij goto err; 203296341Sdelphij } 204238384Sjkim 205296341Sdelphij if (x->n != NULL) 206296341Sdelphij mod_len = BN_num_bits(x->n); 207238384Sjkim 208296341Sdelphij if (!BIO_indent(bp, off, 128)) 209296341Sdelphij goto err; 210238384Sjkim 211296341Sdelphij if (priv && x->d) { 212296341Sdelphij if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) 213296341Sdelphij <= 0) 214296341Sdelphij goto err; 215296341Sdelphij str = "modulus:"; 216296341Sdelphij s = "publicExponent:"; 217296341Sdelphij } else { 218296341Sdelphij if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) 219296341Sdelphij <= 0) 220296341Sdelphij goto err; 221296341Sdelphij str = "Modulus:"; 222296341Sdelphij s = "Exponent:"; 223296341Sdelphij } 224296341Sdelphij if (!ASN1_bn_print(bp, str, x->n, m, off)) 225296341Sdelphij goto err; 226296341Sdelphij if (!ASN1_bn_print(bp, s, x->e, m, off)) 227296341Sdelphij goto err; 228296341Sdelphij if (priv) { 229296341Sdelphij if (!ASN1_bn_print(bp, "privateExponent:", x->d, m, off)) 230296341Sdelphij goto err; 231296341Sdelphij if (!ASN1_bn_print(bp, "prime1:", x->p, m, off)) 232296341Sdelphij goto err; 233296341Sdelphij if (!ASN1_bn_print(bp, "prime2:", x->q, m, off)) 234296341Sdelphij goto err; 235296341Sdelphij if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, m, off)) 236296341Sdelphij goto err; 237296341Sdelphij if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, m, off)) 238296341Sdelphij goto err; 239296341Sdelphij if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, m, off)) 240296341Sdelphij goto err; 241296341Sdelphij } 242296341Sdelphij ret = 1; 243296341Sdelphij err: 244296341Sdelphij if (m != NULL) 245296341Sdelphij OPENSSL_free(m); 246296341Sdelphij return (ret); 247296341Sdelphij} 248238384Sjkim 249238384Sjkimstatic int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 250296341Sdelphij ASN1_PCTX *ctx) 251296341Sdelphij{ 252296341Sdelphij return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); 253296341Sdelphij} 254238384Sjkim 255238384Sjkimstatic int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 256296341Sdelphij ASN1_PCTX *ctx) 257296341Sdelphij{ 258296341Sdelphij return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); 259296341Sdelphij} 260238384Sjkim 261238384Sjkimstatic RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg, 262296341Sdelphij X509_ALGOR **pmaskHash) 263296341Sdelphij{ 264296341Sdelphij const unsigned char *p; 265296341Sdelphij int plen; 266296341Sdelphij RSA_PSS_PARAMS *pss; 267238384Sjkim 268296341Sdelphij *pmaskHash = NULL; 269238384Sjkim 270296341Sdelphij if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) 271296341Sdelphij return NULL; 272296341Sdelphij p = alg->parameter->value.sequence->data; 273296341Sdelphij plen = alg->parameter->value.sequence->length; 274296341Sdelphij pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); 275238384Sjkim 276296341Sdelphij if (!pss) 277296341Sdelphij return NULL; 278238384Sjkim 279296341Sdelphij if (pss->maskGenAlgorithm) { 280296341Sdelphij ASN1_TYPE *param = pss->maskGenAlgorithm->parameter; 281296341Sdelphij if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1 282296341Sdelphij && param && param->type == V_ASN1_SEQUENCE) { 283296341Sdelphij p = param->value.sequence->data; 284296341Sdelphij plen = param->value.sequence->length; 285296341Sdelphij *pmaskHash = d2i_X509_ALGOR(NULL, &p, plen); 286296341Sdelphij } 287296341Sdelphij } 288238384Sjkim 289296341Sdelphij return pss; 290296341Sdelphij} 291238384Sjkim 292296341Sdelphijstatic int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, 293296341Sdelphij X509_ALGOR *maskHash, int indent) 294296341Sdelphij{ 295296341Sdelphij int rv = 0; 296296341Sdelphij if (!pss) { 297296341Sdelphij if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) 298296341Sdelphij return 0; 299296341Sdelphij return 1; 300296341Sdelphij } 301296341Sdelphij if (BIO_puts(bp, "\n") <= 0) 302296341Sdelphij goto err; 303296341Sdelphij if (!BIO_indent(bp, indent, 128)) 304296341Sdelphij goto err; 305296341Sdelphij if (BIO_puts(bp, "Hash Algorithm: ") <= 0) 306296341Sdelphij goto err; 307238384Sjkim 308296341Sdelphij if (pss->hashAlgorithm) { 309296341Sdelphij if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) 310296341Sdelphij goto err; 311296341Sdelphij } else if (BIO_puts(bp, "sha1 (default)") <= 0) 312296341Sdelphij goto err; 313238384Sjkim 314296341Sdelphij if (BIO_puts(bp, "\n") <= 0) 315296341Sdelphij goto err; 316238384Sjkim 317296341Sdelphij if (!BIO_indent(bp, indent, 128)) 318296341Sdelphij goto err; 319238384Sjkim 320296341Sdelphij if (BIO_puts(bp, "Mask Algorithm: ") <= 0) 321296341Sdelphij goto err; 322296341Sdelphij if (pss->maskGenAlgorithm) { 323296341Sdelphij if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0) 324296341Sdelphij goto err; 325296341Sdelphij if (BIO_puts(bp, " with ") <= 0) 326296341Sdelphij goto err; 327296341Sdelphij if (maskHash) { 328296341Sdelphij if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) 329296341Sdelphij goto err; 330296341Sdelphij } else if (BIO_puts(bp, "INVALID") <= 0) 331296341Sdelphij goto err; 332296341Sdelphij } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) 333296341Sdelphij goto err; 334296341Sdelphij BIO_puts(bp, "\n"); 335238384Sjkim 336296341Sdelphij if (!BIO_indent(bp, indent, 128)) 337296341Sdelphij goto err; 338296341Sdelphij if (BIO_puts(bp, "Salt Length: 0x") <= 0) 339296341Sdelphij goto err; 340296341Sdelphij if (pss->saltLength) { 341296341Sdelphij if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) 342296341Sdelphij goto err; 343296341Sdelphij } else if (BIO_puts(bp, "14 (default)") <= 0) 344296341Sdelphij goto err; 345296341Sdelphij BIO_puts(bp, "\n"); 346238384Sjkim 347296341Sdelphij if (!BIO_indent(bp, indent, 128)) 348296341Sdelphij goto err; 349296341Sdelphij if (BIO_puts(bp, "Trailer Field: 0x") <= 0) 350296341Sdelphij goto err; 351296341Sdelphij if (pss->trailerField) { 352296341Sdelphij if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) 353296341Sdelphij goto err; 354296341Sdelphij } else if (BIO_puts(bp, "BC (default)") <= 0) 355296341Sdelphij goto err; 356296341Sdelphij BIO_puts(bp, "\n"); 357238384Sjkim 358296341Sdelphij rv = 1; 359238384Sjkim 360296341Sdelphij err: 361296341Sdelphij return rv; 362296341Sdelphij 363296341Sdelphij} 364296341Sdelphij 365238384Sjkimstatic int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, 366296341Sdelphij const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) 367296341Sdelphij{ 368296341Sdelphij if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) { 369296341Sdelphij int rv; 370296341Sdelphij RSA_PSS_PARAMS *pss; 371296341Sdelphij X509_ALGOR *maskHash; 372296341Sdelphij pss = rsa_pss_decode(sigalg, &maskHash); 373296341Sdelphij rv = rsa_pss_param_print(bp, pss, maskHash, indent); 374296341Sdelphij if (pss) 375296341Sdelphij RSA_PSS_PARAMS_free(pss); 376296341Sdelphij if (maskHash) 377296341Sdelphij X509_ALGOR_free(maskHash); 378296341Sdelphij if (!rv) 379296341Sdelphij return 0; 380296341Sdelphij } else if (!sig && BIO_puts(bp, "\n") <= 0) 381296341Sdelphij return 0; 382296341Sdelphij if (sig) 383296341Sdelphij return X509_signature_dump(bp, sig, indent); 384296341Sdelphij return 1; 385296341Sdelphij} 386238384Sjkim 387238384Sjkimstatic int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 388296341Sdelphij{ 389296341Sdelphij X509_ALGOR *alg = NULL; 390296341Sdelphij switch (op) { 391238384Sjkim 392296341Sdelphij case ASN1_PKEY_CTRL_PKCS7_SIGN: 393296341Sdelphij if (arg1 == 0) 394296341Sdelphij PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); 395296341Sdelphij break; 396238384Sjkim 397296341Sdelphij case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 398296341Sdelphij if (arg1 == 0) 399296341Sdelphij PKCS7_RECIP_INFO_get0_alg(arg2, &alg); 400296341Sdelphij break; 401238384Sjkim#ifndef OPENSSL_NO_CMS 402296341Sdelphij case ASN1_PKEY_CTRL_CMS_SIGN: 403296341Sdelphij if (arg1 == 0) 404296341Sdelphij CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg); 405296341Sdelphij break; 406238384Sjkim 407296341Sdelphij case ASN1_PKEY_CTRL_CMS_ENVELOPE: 408296341Sdelphij if (arg1 == 0) 409296341Sdelphij CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg); 410296341Sdelphij break; 411238384Sjkim#endif 412238384Sjkim 413296341Sdelphij case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 414296341Sdelphij *(int *)arg2 = NID_sha1; 415296341Sdelphij return 1; 416238384Sjkim 417296341Sdelphij default: 418296341Sdelphij return -2; 419238384Sjkim 420296341Sdelphij } 421238384Sjkim 422296341Sdelphij if (alg) 423296341Sdelphij X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); 424238384Sjkim 425296341Sdelphij return 1; 426238384Sjkim 427296341Sdelphij} 428238384Sjkim 429296341Sdelphij/* 430296341Sdelphij * Customised RSA item verification routine. This is called when a signature 431296341Sdelphij * is encountered requiring special handling. We currently only handle PSS. 432238384Sjkim */ 433238384Sjkim 434238384Sjkimstatic int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, 435296341Sdelphij X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, 436296341Sdelphij EVP_PKEY *pkey) 437296341Sdelphij{ 438296341Sdelphij int rv = -1; 439296341Sdelphij int saltlen; 440296341Sdelphij const EVP_MD *mgf1md = NULL, *md = NULL; 441296341Sdelphij RSA_PSS_PARAMS *pss; 442296341Sdelphij X509_ALGOR *maskHash; 443296341Sdelphij EVP_PKEY_CTX *pkctx; 444296341Sdelphij /* Sanity check: make sure it is PSS */ 445296341Sdelphij if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { 446296341Sdelphij RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); 447296341Sdelphij return -1; 448296341Sdelphij } 449296341Sdelphij /* Decode PSS parameters */ 450296341Sdelphij pss = rsa_pss_decode(sigalg, &maskHash); 451238384Sjkim 452296341Sdelphij if (pss == NULL) { 453296341Sdelphij RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS); 454296341Sdelphij goto err; 455296341Sdelphij } 456296341Sdelphij /* Check mask and lookup mask hash algorithm */ 457296341Sdelphij if (pss->maskGenAlgorithm) { 458296341Sdelphij if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1) { 459296341Sdelphij RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM); 460296341Sdelphij goto err; 461296341Sdelphij } 462296341Sdelphij if (!maskHash) { 463296341Sdelphij RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER); 464296341Sdelphij goto err; 465296341Sdelphij } 466296341Sdelphij mgf1md = EVP_get_digestbyobj(maskHash->algorithm); 467296341Sdelphij if (mgf1md == NULL) { 468296341Sdelphij RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST); 469296341Sdelphij goto err; 470296341Sdelphij } 471296341Sdelphij } else 472296341Sdelphij mgf1md = EVP_sha1(); 473238384Sjkim 474296341Sdelphij if (pss->hashAlgorithm) { 475296341Sdelphij md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm); 476296341Sdelphij if (md == NULL) { 477296341Sdelphij RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST); 478296341Sdelphij goto err; 479296341Sdelphij } 480296341Sdelphij } else 481296341Sdelphij md = EVP_sha1(); 482238384Sjkim 483296341Sdelphij if (pss->saltLength) { 484296341Sdelphij saltlen = ASN1_INTEGER_get(pss->saltLength); 485238384Sjkim 486296341Sdelphij /* 487296341Sdelphij * Could perform more salt length sanity checks but the main RSA 488296341Sdelphij * routines will trap other invalid values anyway. 489296341Sdelphij */ 490296341Sdelphij if (saltlen < 0) { 491296341Sdelphij RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH); 492296341Sdelphij goto err; 493296341Sdelphij } 494296341Sdelphij } else 495296341Sdelphij saltlen = 20; 496238384Sjkim 497296341Sdelphij /* 498296341Sdelphij * low-level routines support only trailer field 0xbc (value 1) and 499296341Sdelphij * PKCS#1 says we should reject any other value anyway. 500296341Sdelphij */ 501296341Sdelphij if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { 502296341Sdelphij RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER); 503296341Sdelphij goto err; 504296341Sdelphij } 505238384Sjkim 506296341Sdelphij /* We have all parameters now set up context */ 507238384Sjkim 508296341Sdelphij if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) 509296341Sdelphij goto err; 510238384Sjkim 511296341Sdelphij if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) 512296341Sdelphij goto err; 513238384Sjkim 514296341Sdelphij if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) 515296341Sdelphij goto err; 516238384Sjkim 517296341Sdelphij if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) 518296341Sdelphij goto err; 519296341Sdelphij /* Carry on */ 520296341Sdelphij rv = 2; 521238384Sjkim 522296341Sdelphij err: 523296341Sdelphij RSA_PSS_PARAMS_free(pss); 524296341Sdelphij if (maskHash) 525296341Sdelphij X509_ALGOR_free(maskHash); 526296341Sdelphij return rv; 527296341Sdelphij} 528238384Sjkim 529238384Sjkimstatic int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, 530296341Sdelphij X509_ALGOR *alg1, X509_ALGOR *alg2, 531296341Sdelphij ASN1_BIT_STRING *sig) 532296341Sdelphij{ 533296341Sdelphij int pad_mode; 534296341Sdelphij EVP_PKEY_CTX *pkctx = ctx->pctx; 535296341Sdelphij if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) 536296341Sdelphij return 0; 537296341Sdelphij if (pad_mode == RSA_PKCS1_PADDING) 538296341Sdelphij return 2; 539296341Sdelphij if (pad_mode == RSA_PKCS1_PSS_PADDING) { 540296341Sdelphij const EVP_MD *sigmd, *mgf1md; 541296341Sdelphij RSA_PSS_PARAMS *pss = NULL; 542296341Sdelphij X509_ALGOR *mgf1alg = NULL; 543296341Sdelphij ASN1_STRING *os1 = NULL, *os2 = NULL; 544296341Sdelphij EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); 545296341Sdelphij int saltlen, rv = 0; 546296341Sdelphij sigmd = EVP_MD_CTX_md(ctx); 547296341Sdelphij if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) 548296341Sdelphij goto err; 549296341Sdelphij if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) 550296341Sdelphij goto err; 551296341Sdelphij if (saltlen == -1) 552296341Sdelphij saltlen = EVP_MD_size(sigmd); 553296341Sdelphij else if (saltlen == -2) { 554296341Sdelphij saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; 555296341Sdelphij if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) 556296341Sdelphij saltlen--; 557296341Sdelphij } 558296341Sdelphij pss = RSA_PSS_PARAMS_new(); 559296341Sdelphij if (!pss) 560296341Sdelphij goto err; 561296341Sdelphij if (saltlen != 20) { 562296341Sdelphij pss->saltLength = ASN1_INTEGER_new(); 563296341Sdelphij if (!pss->saltLength) 564296341Sdelphij goto err; 565296341Sdelphij if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) 566296341Sdelphij goto err; 567296341Sdelphij } 568296341Sdelphij if (EVP_MD_type(sigmd) != NID_sha1) { 569296341Sdelphij pss->hashAlgorithm = X509_ALGOR_new(); 570296341Sdelphij if (!pss->hashAlgorithm) 571296341Sdelphij goto err; 572296341Sdelphij X509_ALGOR_set_md(pss->hashAlgorithm, sigmd); 573296341Sdelphij } 574296341Sdelphij if (EVP_MD_type(mgf1md) != NID_sha1) { 575296341Sdelphij ASN1_STRING *stmp = NULL; 576296341Sdelphij /* need to embed algorithm ID inside another */ 577296341Sdelphij mgf1alg = X509_ALGOR_new(); 578296341Sdelphij X509_ALGOR_set_md(mgf1alg, mgf1md); 579296341Sdelphij if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) 580296341Sdelphij goto err; 581296341Sdelphij pss->maskGenAlgorithm = X509_ALGOR_new(); 582296341Sdelphij if (!pss->maskGenAlgorithm) 583296341Sdelphij goto err; 584296341Sdelphij X509_ALGOR_set0(pss->maskGenAlgorithm, 585296341Sdelphij OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); 586296341Sdelphij } 587296341Sdelphij /* Finally create string with pss parameter encoding. */ 588296341Sdelphij if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1)) 589296341Sdelphij goto err; 590296341Sdelphij if (alg2) { 591296341Sdelphij os2 = ASN1_STRING_dup(os1); 592296341Sdelphij if (!os2) 593296341Sdelphij goto err; 594296341Sdelphij X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), 595296341Sdelphij V_ASN1_SEQUENCE, os2); 596296341Sdelphij } 597296341Sdelphij X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), 598296341Sdelphij V_ASN1_SEQUENCE, os1); 599296341Sdelphij os1 = os2 = NULL; 600296341Sdelphij rv = 3; 601296341Sdelphij err: 602296341Sdelphij if (mgf1alg) 603296341Sdelphij X509_ALGOR_free(mgf1alg); 604296341Sdelphij if (pss) 605296341Sdelphij RSA_PSS_PARAMS_free(pss); 606296341Sdelphij if (os1) 607296341Sdelphij ASN1_STRING_free(os1); 608296341Sdelphij return rv; 609238384Sjkim 610296341Sdelphij } 611296341Sdelphij return 2; 612296341Sdelphij} 613238384Sjkim 614296341Sdelphijconst EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = { 615296341Sdelphij { 616296341Sdelphij EVP_PKEY_RSA, 617296341Sdelphij EVP_PKEY_RSA, 618296341Sdelphij ASN1_PKEY_SIGPARAM_NULL, 619238384Sjkim 620296341Sdelphij "RSA", 621296341Sdelphij "OpenSSL RSA method", 622238384Sjkim 623296341Sdelphij rsa_pub_decode, 624296341Sdelphij rsa_pub_encode, 625296341Sdelphij rsa_pub_cmp, 626296341Sdelphij rsa_pub_print, 627238384Sjkim 628296341Sdelphij rsa_priv_decode, 629296341Sdelphij rsa_priv_encode, 630296341Sdelphij rsa_priv_print, 631238384Sjkim 632296341Sdelphij int_rsa_size, 633296341Sdelphij rsa_bits, 634238384Sjkim 635296341Sdelphij 0, 0, 0, 0, 0, 0, 636238384Sjkim 637296341Sdelphij rsa_sig_print, 638296341Sdelphij int_rsa_free, 639296341Sdelphij rsa_pkey_ctrl, 640296341Sdelphij old_rsa_priv_decode, 641296341Sdelphij old_rsa_priv_encode, 642296341Sdelphij rsa_item_verify, 643296341Sdelphij rsa_item_sign}, 644296341Sdelphij 645296341Sdelphij { 646296341Sdelphij EVP_PKEY_RSA2, 647296341Sdelphij EVP_PKEY_RSA, 648296341Sdelphij ASN1_PKEY_ALIAS} 649296341Sdelphij}; 650