Example #1
0
/* rsa_ctx_to_pss converts EVP_PKEY_CTX in PSS mode into corresponding
 * algorithm parameter, suitable for setting as an AlgorithmIdentifier. */
static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) {
  const EVP_MD *sigmd, *mgf1md;
  RSA_PSS_PARAMS *pss = NULL;
  ASN1_STRING *os = NULL;
  EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
  int saltlen, rv = 0;

  if (!EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) ||
      !EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) ||
      !EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) {
    goto err;
  }

  if (saltlen == -1) {
    saltlen = EVP_MD_size(sigmd);
  } else if (saltlen == -2) {
    saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
    if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
      saltlen--;
    }
  } else {
    goto err;
  }

  pss = RSA_PSS_PARAMS_new();
  if (!pss) {
    goto err;
  }

  if (saltlen != 20) {
    pss->saltLength = ASN1_INTEGER_new();
    if (!pss->saltLength ||
        !ASN1_INTEGER_set(pss->saltLength, saltlen)) {
      goto err;
    }
  }

  if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) ||
      !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) {
    goto err;
  }

  /* Finally create string with pss parameter encoding. */
  if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
    goto err;
  }
  rv = 1;

err:
  if (pss) {
    RSA_PSS_PARAMS_free(pss);
  }
  if (rv) {
    return os;
  }
  if (os) {
    ASN1_STRING_free(os);
  }
  return NULL;
}
Example #2
0
static int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg,
                            const ASN1_STRING *sig)
{
    int rv = 0;
    int mdnid, saltlen;
    uint32_t flags;
    const EVP_MD *mgf1md = NULL, *md = NULL;
    RSA_PSS_PARAMS *pss;

    /* Sanity check: make sure it is PSS */
    if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS)
        return 0;
    /* Decode PSS parameters */
    pss = rsa_pss_decode(sigalg);
    if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen))
        goto err;
    mdnid = EVP_MD_type(md);
    /*
     * For TLS need SHA256, SHA384 or SHA512, digest and MGF1 digest must
     * match and salt length must equal digest size
     */
    if ((mdnid == NID_sha256 || mdnid == NID_sha384 || mdnid == NID_sha512)
            && mdnid == EVP_MD_type(mgf1md) && saltlen == EVP_MD_size(md))
        flags = X509_SIG_INFO_TLS;
    else
        flags = 0;
    /* Note: security bits half number of digest bits */
    X509_SIG_INFO_set(siginf, mdnid, EVP_PKEY_RSA_PSS, EVP_MD_size(md) * 4,
                      flags);
    rv = 1;
    err:
    RSA_PSS_PARAMS_free(pss);
    return rv;
}
Example #3
0
RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd,
                                      const EVP_MD *mgf1md, int saltlen)
{
    RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new();

    if (pss == NULL)
        goto err;
    if (saltlen != 20) {
        pss->saltLength = ASN1_INTEGER_new();
        if (pss->saltLength == NULL)
            goto err;
        if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
            goto err;
    }
    if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd))
        goto err;
    if (mgf1md == NULL)
        mgf1md = sigmd;
    if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md))
        goto err;
    if (!rsa_md_to_algor(&pss->maskHash, mgf1md))
        goto err;
    return pss;
 err:
    RSA_PSS_PARAMS_free(pss);
    return NULL;
}
Example #4
0
int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
  const EVP_MD *sigmd, *mgf1md;
  int saltlen;
  if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) ||
      !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) ||
      !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) {
    return 0;
  }

  EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
  if (saltlen == -1) {
    saltlen = EVP_MD_size(sigmd);
  } else if (saltlen == -2) {
    saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
    if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
      saltlen--;
    }
  } else {
    return 0;
  }

  int ret = 0;
  ASN1_STRING *os = NULL;
  RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new();
  if (!pss) {
    goto err;
  }

  if (saltlen != 20) {
    pss->saltLength = ASN1_INTEGER_new();
    if (!pss->saltLength ||
        !ASN1_INTEGER_set(pss->saltLength, saltlen)) {
      goto err;
    }
  }

  if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) ||
      !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) {
    goto err;
  }

  /* Finally create string with pss parameter encoding. */
  if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
    goto err;
  }

  X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os);
  os = NULL;
  ret = 1;

err:
  RSA_PSS_PARAMS_free(pss);
  ASN1_STRING_free(os);
  return ret;
}
Example #5
0
static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx)
{
    RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx);
    ASN1_STRING *os;

    if (pss == NULL)
        return NULL;

    os = ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), NULL);
    RSA_PSS_PARAMS_free(pss);
    return os;
}
Example #6
0
int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
  assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss);

  /* Decode PSS parameters */
  int ret = 0;
  X509_ALGOR *maskHash;
  RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash);
  if (pss == NULL) {
    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
    goto err;
  }

  const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
  const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm);
  if (mgf1md == NULL || md == NULL) {
    goto err;
  }

  int saltlen = 20;
  if (pss->saltLength != NULL) {
    saltlen = ASN1_INTEGER_get(pss->saltLength);

    /* Could perform more salt length sanity checks but the main
     * RSA routines will trap other invalid values anyway. */
    if (saltlen < 0) {
      OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
      goto err;
    }
  }

  /* low-level routines support only trailer field 0xbc (value 1)
   * and PKCS#1 says we should reject any other value anyway. */
  if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) {
    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
    goto err;
  }

  EVP_PKEY_CTX *pctx;
  if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) ||
      !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
      !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, saltlen) ||
      !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) {
    goto err;
  }

  ret = 1;

err:
  RSA_PSS_PARAMS_free(pss);
  X509_ALGOR_free(maskHash);
  return ret;
}
Example #7
0
static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
                          X509_ALGOR *sigalg, EVP_PKEY *pkey)
{
    int rv = -1;
    int saltlen;
    const EVP_MD *mgf1md = NULL, *md = NULL;
    RSA_PSS_PARAMS *pss;

    /* Sanity check: make sure it is PSS */
    if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) {
        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
        return -1;
    }
    /* Decode PSS parameters */
    pss = rsa_pss_decode(sigalg);

    if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) {
        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS);
        goto err;
    }

    /* We have all parameters now set up context */
    if (pkey) {
        if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
            goto err;
    } else {
        const EVP_MD *checkmd;
        if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0)
            goto err;
        if (EVP_MD_type(md) != EVP_MD_type(checkmd)) {
            RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH);
            goto err;
        }
    }

    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
        goto err;

    if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
        goto err;

    if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
        goto err;
    /* Carry on */
    rv = 1;

 err:
    RSA_PSS_PARAMS_free(pss);
    return rv;
}
Example #8
0
static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
{
    if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) {
        int rv;
        RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg);

        rv = rsa_pss_param_print(bp, 0, pss, indent);
        RSA_PSS_PARAMS_free(pss);
        if (!rv)
            return 0;
    } else if (!sig && BIO_puts(bp, "\n") <= 0) {
        return 0;
    }
    if (sig)
        return X509_signature_dump(bp, sig, indent);
    return 1;
}
Example #9
0
static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
{
    if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) {
        int rv;
        RSA_PSS_PARAMS *pss;
        X509_ALGOR *maskHash;
        pss = rsa_pss_decode(sigalg, &maskHash);
        rv = rsa_pss_param_print(bp, pss, maskHash, indent);
        RSA_PSS_PARAMS_free(pss);
        X509_ALGOR_free(maskHash);
        if (!rv)
            return 0;
    } else if (!sig && BIO_puts(bp, "\n") <= 0)
        return 0;
    if (sig)
        return X509_signature_dump(bp, sig, indent);
    return 1;
}
Example #10
0
static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg)
{
    RSA_PSS_PARAMS *pss;

    pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS),
                                    alg->parameter);

    if (pss == NULL)
        return NULL;

    if (pss->maskGenAlgorithm != NULL) {
        pss->maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
        if (pss->maskHash == NULL) {
            RSA_PSS_PARAMS_free(pss);
            return NULL;
        }
    }

    return pss;
}
Example #11
0
void RSA_free(RSA *r)
{
    int i;

    if (r == NULL)
        return;

    CRYPTO_DOWN_REF(&r->references, &i, r->lock);
    REF_PRINT_COUNT("RSA", r);
    if (i > 0)
        return;
    REF_ASSERT_ISNT(i < 0);

    if (r->meth->finish)
        r->meth->finish(r);
#ifndef OPENSSL_NO_ENGINE
    ENGINE_finish(r->engine);
#endif

    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);

    CRYPTO_THREAD_lock_free(r->lock);

    BN_clear_free(r->n);
    BN_clear_free(r->e);
    BN_clear_free(r->d);
    BN_clear_free(r->p);
    BN_clear_free(r->q);
    BN_clear_free(r->dmp1);
    BN_clear_free(r->dmq1);
    BN_clear_free(r->iqmp);
    RSA_PSS_PARAMS_free(r->pss);
    sk_RSA_PRIME_INFO_pop_free(r->prime_infos, rsa_multip_info_free);
    BN_BLINDING_free(r->blinding);
    BN_BLINDING_free(r->mt_blinding);
    OPENSSL_free(r->bignum_data);
    OPENSSL_free(r);
}
Example #12
0
int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent,
                              ASN1_PCTX *pctx) {
  assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss);

  int rv = 0;
  X509_ALGOR *maskHash;
  RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash);
  if (!pss) {
    if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) {
      goto err;
    }
    rv = 1;
    goto err;
  }

  if (BIO_puts(bp, "\n") <= 0 ||
      !BIO_indent(bp, indent, 128) ||
      BIO_puts(bp, "Hash Algorithm: ") <= 0) {
    goto err;
  }

  if (pss->hashAlgorithm) {
    if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) {
      goto err;
    }
  } else if (BIO_puts(bp, "sha1 (default)") <= 0) {
    goto err;
  }

  if (BIO_puts(bp, "\n") <= 0 ||
      !BIO_indent(bp, indent, 128) ||
      BIO_puts(bp, "Mask Algorithm: ") <= 0) {
    goto err;
  }

  if (pss->maskGenAlgorithm) {
    if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 ||
        BIO_puts(bp, " with ") <= 0) {
      goto err;
    }

    if (maskHash) {
      if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) {
        goto err;
      }
    } else if (BIO_puts(bp, "INVALID") <= 0) {
      goto err;
    }
  } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) {
    goto err;
  }
  BIO_puts(bp, "\n");

  if (!BIO_indent(bp, indent, 128) ||
      BIO_puts(bp, "Salt Length: 0x") <= 0) {
    goto err;
  }

  if (pss->saltLength) {
    if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) {
      goto err;
    }
  } else if (BIO_puts(bp, "14 (default)") <= 0) {
    goto err;
  }
  BIO_puts(bp, "\n");

  if (!BIO_indent(bp, indent, 128) ||
      BIO_puts(bp, "Trailer Field: 0x") <= 0) {
    goto err;
  }

  if (pss->trailerField) {
    if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) {
      goto err;
    }
  } else if (BIO_puts(bp, "BC (default)") <= 0) {
    goto err;
  }
  BIO_puts(bp, "\n");

  rv = 1;

err:
  RSA_PSS_PARAMS_free(pss);
  X509_ALGOR_free(maskHash);
  return rv;
}
Example #13
0
static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
                          X509_ALGOR *sigalg, EVP_PKEY *pkey)
{
    int rv = -1;
    int saltlen;
    const EVP_MD *mgf1md = NULL, *md = NULL;
    RSA_PSS_PARAMS *pss;
    X509_ALGOR *maskHash;
    /* Sanity check: make sure it is PSS */
    if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
        return -1;
    }
    /* Decode PSS parameters */
    pss = rsa_pss_decode(sigalg, &maskHash);

    if (pss == NULL) {
        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS);
        goto err;
    }
    mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
    if (!mgf1md)
        goto err;
    md = rsa_algor_to_md(pss->hashAlgorithm);
    if (!md)
        goto err;

    if (pss->saltLength) {
        saltlen = ASN1_INTEGER_get(pss->saltLength);

        /*
         * Could perform more salt length sanity checks but the main RSA
         * routines will trap other invalid values anyway.
         */
        if (saltlen < 0) {
            RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_SALT_LENGTH);
            goto err;
        }
    } else
        saltlen = 20;

    /*
     * low-level routines support only trailer field 0xbc (value 1) and
     * PKCS#1 says we should reject any other value anyway.
     */
    if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_TRAILER);
        goto err;
    }

    /* We have all parameters now set up context */

    if (pkey) {
        if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
            goto err;
    } else {
        const EVP_MD *checkmd;
        if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0)
            goto err;
        if (EVP_MD_type(md) != EVP_MD_type(checkmd)) {
            RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH);
            goto err;
        }
    }

    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
        goto err;

    if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
        goto err;

    if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
        goto err;
    /* Carry on */
    rv = 1;

 err:
    RSA_PSS_PARAMS_free(pss);
    X509_ALGOR_free(maskHash);
    return rv;
}
Example #14
0
static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
                         X509_ALGOR *alg1, X509_ALGOR *alg2,
                         ASN1_BIT_STRING *sig)
{
    int pad_mode;
    EVP_PKEY_CTX *pkctx = ctx->pctx;
    if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
        return 0;
    if (pad_mode == RSA_PKCS1_PADDING)
        return 2;
    if (pad_mode == RSA_PKCS1_PSS_PADDING)
    {
        const EVP_MD *sigmd, *mgf1md;
        RSA_PSS_PARAMS *pss = NULL;
        X509_ALGOR *mgf1alg = NULL;
        ASN1_STRING *os1 = NULL, *os2 = NULL;
        EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
        int saltlen, rv = 0;
        sigmd = EVP_MD_CTX_md(ctx);
        if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
            goto err;
        if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
            goto err;
        if (saltlen == -1)
            saltlen = EVP_MD_size(sigmd);
        else if (saltlen == -2)
        {
            saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
            if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0)
                saltlen--;
        }
        pss = RSA_PSS_PARAMS_new();
        if (!pss)
            goto err;
        if (saltlen != 20)
        {
            pss->saltLength = ASN1_INTEGER_new();
            if (!pss->saltLength)
                goto err;
            if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
                goto err;
        }
        if (EVP_MD_type(sigmd) != NID_sha1)
        {
            pss->hashAlgorithm = X509_ALGOR_new();
            if (!pss->hashAlgorithm)
                goto err;
            X509_ALGOR_set_md(pss->hashAlgorithm, sigmd);
        }
        if (EVP_MD_type(mgf1md) != NID_sha1)
        {
            ASN1_STRING *stmp = NULL;
            /* need to embed algorithm ID inside another */
            mgf1alg = X509_ALGOR_new();
            X509_ALGOR_set_md(mgf1alg, mgf1md);
            if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR),
                                &stmp))
                goto err;
            pss->maskGenAlgorithm = X509_ALGOR_new();
            if (!pss->maskGenAlgorithm)
                goto err;
            X509_ALGOR_set0(pss->maskGenAlgorithm,
                            OBJ_nid2obj(NID_mgf1),
                            V_ASN1_SEQUENCE, stmp);
        }
        /* Finally create string with pss parameter encoding. */
        if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1))
            goto err;
        if (alg2)
        {
            os2 = ASN1_STRING_dup(os1);
            if (!os2)
                goto err;
            X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss),
                            V_ASN1_SEQUENCE, os2);
        }
        X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss),
                        V_ASN1_SEQUENCE, os1);
        os1 = os2 = NULL;
        rv = 3;
err:
        if (mgf1alg)
            X509_ALGOR_free(mgf1alg);
        if (pss)
            RSA_PSS_PARAMS_free(pss);
        if (os1)
            ASN1_STRING_free(os1);
        return rv;

    }
    return 2;
}
Example #15
0
static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
                           X509_ALGOR *sigalg, ASN1_BIT_STRING *sig,
                           EVP_PKEY *pkey)
{
    int rv = -1;
    int saltlen;
    const EVP_MD *mgf1md = NULL, *md = NULL;
    RSA_PSS_PARAMS *pss;
    X509_ALGOR *maskHash;
    EVP_PKEY_CTX *pkctx;
    /* Sanity check: make sure it is PSS */
    if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss)
    {
        RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
        return -1;
    }
    /* Decode PSS parameters */
    pss = rsa_pss_decode(sigalg, &maskHash);

    if (pss == NULL)
    {
        RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS);
        goto err;
    }
    /* Check mask and lookup mask hash algorithm */
    if (pss->maskGenAlgorithm)
    {
        if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1)
        {
            RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM);
            goto err;
        }
        if (!maskHash)
        {
            RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER);
            goto err;
        }
        mgf1md = EVP_get_digestbyobj(maskHash->algorithm);
        if (mgf1md == NULL)
        {
            RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST);
            goto err;
        }
    }
    else
        mgf1md = EVP_sha1();

    if (pss->hashAlgorithm)
    {
        md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm);
        if (md == NULL)
        {
            RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST);
            goto err;
        }
    }
    else
        md = EVP_sha1();

    if (pss->saltLength)
    {
        saltlen = ASN1_INTEGER_get(pss->saltLength);

        /* Could perform more salt length sanity checks but the main
         * RSA routines will trap other invalid values anyway.
         */
        if (saltlen < 0)
        {
            RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH);
            goto err;
        }
    }
    else
        saltlen = 20;

    /* low-level routines support only trailer field 0xbc (value 1)
     * and PKCS#1 says we should reject any other value anyway.
     */
    if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1)
    {
        RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER);
        goto err;
    }

    /* We have all parameters now set up context */

    if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
        goto err;

    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
        goto err;

    if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
        goto err;

    if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
        goto err;
    /* Carry on */
    rv = 2;

err:
    RSA_PSS_PARAMS_free(pss);
    if (maskHash)
        X509_ALGOR_free(maskHash);
    return rv;
}
Example #16
0
/* From PSS AlgorithmIdentifier set public key parameters. */
static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
  int ret = 0;
  int saltlen;
  const EVP_MD *mgf1md = NULL, *md = NULL;
  RSA_PSS_PARAMS *pss;
  X509_ALGOR *maskHash;
  EVP_PKEY_CTX *pkctx;

  /* Sanity check: make sure it is PSS */
  if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
    OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
    return 0;
  }
  /* Decode PSS parameters */
  pss = rsa_pss_decode(sigalg, &maskHash);
  if (pss == NULL) {
    OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_PSS_PARAMETERS);
    goto err;
  }

  mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
  if (!mgf1md) {
    goto err;
  }
  md = rsa_algor_to_md(pss->hashAlgorithm);
  if (!md) {
    goto err;
  }

  saltlen = 20;
  if (pss->saltLength) {
    saltlen = ASN1_INTEGER_get(pss->saltLength);

    /* Could perform more salt length sanity checks but the main
     * RSA routines will trap other invalid values anyway. */
    if (saltlen < 0) {
      OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_SALT_LENGTH);
      goto err;
    }
  }

  /* low-level routines support only trailer field 0xbc (value 1)
   * and PKCS#1 says we should reject any other value anyway. */
  if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
    OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_TRAILER);
    goto err;
  }

  if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) ||
      !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) ||
      !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) ||
      !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) {
    goto err;
  }

  ret = 1;

err:
  RSA_PSS_PARAMS_free(pss);
  if (maskHash) {
    X509_ALGOR_free(maskHash);
  }
  return ret;
}