src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java
author valeriep
Mon, 23 Jul 2018 23:18:19 +0000
changeset 51229 17b7d7034e8e
parent 50715 46492a773912
permissions -rw-r--r--
8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized Summary: Changed SunRsaSign and SunMSCAPI provider to return null and updated javadoc Reviewed-by: weijun, mullan
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50204
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
     1
/*
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
     2
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
     4
 *
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    10
 *
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    15
 * accompanied this code).
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    16
 *
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    20
 *
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    23
 * questions.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    24
 */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    25
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    26
package sun.security.rsa;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    27
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    28
import java.io.IOException;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    29
import java.nio.ByteBuffer;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    30
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    31
import java.security.*;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    32
import java.security.spec.AlgorithmParameterSpec;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    33
import java.security.spec.PSSParameterSpec;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    34
import java.security.spec.MGF1ParameterSpec;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    35
import java.security.interfaces.*;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    36
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    37
import java.util.Arrays;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    38
import java.util.Hashtable;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    39
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    40
import sun.security.util.*;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    41
import sun.security.jca.JCAUtil;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    42
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    43
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    44
/**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    45
 * PKCS#1 v2.2 RSASSA-PSS signatures with various message digest algorithms.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    46
 * RSASSA-PSS implementation takes the message digest algorithm, MGF algorithm,
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    47
 * and salt length values through the required signature PSS parameters.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    48
 * We support SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    49
 * SHA-512/256 message digest algorithms and MGF1 mask generation function.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    50
 *
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    51
 * @since   11
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    52
 */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    53
public class RSAPSSSignature extends SignatureSpi {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    54
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    55
    private static final boolean DEBUG = false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    56
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    57
    // utility method for comparing digest algorithms
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    58
    // NOTE that first argument is assumed to be standard digest name
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    59
    private boolean isDigestEqual(String stdAlg, String givenAlg) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    60
        if (stdAlg == null || givenAlg == null) return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    61
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    62
        if (givenAlg.indexOf("-") != -1) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    63
            return stdAlg.equalsIgnoreCase(givenAlg);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    64
        } else {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    65
            if (stdAlg.equals("SHA-1")) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    66
                return (givenAlg.equalsIgnoreCase("SHA")
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    67
                        || givenAlg.equalsIgnoreCase("SHA1"));
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    68
            } else {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    69
                StringBuilder sb = new StringBuilder(givenAlg);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    70
                // case-insensitive check
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    71
                if (givenAlg.regionMatches(true, 0, "SHA", 0, 3)) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    72
                    givenAlg = sb.insert(3, "-").toString();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    73
                    return stdAlg.equalsIgnoreCase(givenAlg);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    74
                } else {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    75
                    throw new ProviderException("Unsupported digest algorithm "
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    76
                            + givenAlg);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    77
                }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    78
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    79
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    80
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    81
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    82
    private static final byte[] EIGHT_BYTES_OF_ZEROS = new byte[8];
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    83
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    84
    private static final Hashtable<String, Integer> DIGEST_LENGTHS =
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    85
        new Hashtable<String, Integer>();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    86
    static {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    87
        DIGEST_LENGTHS.put("SHA-1", 20);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    88
        DIGEST_LENGTHS.put("SHA", 20);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    89
        DIGEST_LENGTHS.put("SHA1", 20);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    90
        DIGEST_LENGTHS.put("SHA-224", 28);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    91
        DIGEST_LENGTHS.put("SHA224", 28);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    92
        DIGEST_LENGTHS.put("SHA-256", 32);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    93
        DIGEST_LENGTHS.put("SHA256", 32);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    94
        DIGEST_LENGTHS.put("SHA-384", 48);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    95
        DIGEST_LENGTHS.put("SHA384", 48);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    96
        DIGEST_LENGTHS.put("SHA-512", 64);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    97
        DIGEST_LENGTHS.put("SHA512", 64);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    98
        DIGEST_LENGTHS.put("SHA-512/224", 28);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
    99
        DIGEST_LENGTHS.put("SHA512/224", 28);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   100
        DIGEST_LENGTHS.put("SHA-512/256", 32);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   101
        DIGEST_LENGTHS.put("SHA512/256", 32);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   102
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   103
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   104
    // message digest implementation we use for hashing the data
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   105
    private MessageDigest md;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   106
    // flag indicating whether the digest is reset
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   107
    private boolean digestReset = true;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   108
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   109
    // private key, if initialized for signing
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   110
    private RSAPrivateKey privKey = null;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   111
    // public key, if initialized for verifying
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   112
    private RSAPublicKey pubKey = null;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   113
    // PSS parameters from signatures and keys respectively
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   114
    private PSSParameterSpec sigParams = null; // required for PSS signatures
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   115
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   116
    // PRNG used to generate salt bytes if none given
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   117
    private SecureRandom random;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   118
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   119
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   120
     * Construct a new RSAPSSSignatur with arbitrary digest algorithm
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   121
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   122
    public RSAPSSSignature() {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   123
        this.md = null;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   124
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   125
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   126
    // initialize for verification. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   127
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   128
    protected void engineInitVerify(PublicKey publicKey)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   129
            throws InvalidKeyException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   130
        if (!(publicKey instanceof RSAPublicKey)) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   131
            throw new InvalidKeyException("key must be RSAPublicKey");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   132
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   133
        this.pubKey = (RSAPublicKey) isValid((RSAKey)publicKey);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   134
        this.privKey = null;
50715
46492a773912 8205445: Add RSASSA-PSS Signature support to SunMSCAPI
weijun
parents: 50204
diff changeset
   135
        resetDigest();
50204
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   136
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   137
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   138
    // initialize for signing. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   139
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   140
    protected void engineInitSign(PrivateKey privateKey)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   141
            throws InvalidKeyException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   142
        engineInitSign(privateKey, null);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   143
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   144
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   145
    // initialize for signing. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   146
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   147
    protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   148
            throws InvalidKeyException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   149
        if (!(privateKey instanceof RSAPrivateKey)) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   150
            throw new InvalidKeyException("key must be RSAPrivateKey");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   151
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   152
        this.privKey = (RSAPrivateKey) isValid((RSAKey)privateKey);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   153
        this.pubKey = null;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   154
        this.random =
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   155
            (random == null? JCAUtil.getSecureRandom() : random);
50715
46492a773912 8205445: Add RSASSA-PSS Signature support to SunMSCAPI
weijun
parents: 50204
diff changeset
   156
        resetDigest();
50204
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   157
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   158
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   159
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   160
     * Utility method for checking the key PSS parameters against signature
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   161
     * PSS parameters.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   162
     * Returns false if any of the digest/MGF algorithms and trailerField
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   163
     * values does not match or if the salt length in key parameters is
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   164
     * larger than the value in signature parameters.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   165
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   166
    private static boolean isCompatible(AlgorithmParameterSpec keyParams,
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   167
            PSSParameterSpec sigParams) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   168
        if (keyParams == null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   169
            // key with null PSS parameters means no restriction
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   170
            return true;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   171
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   172
        if (!(keyParams instanceof PSSParameterSpec)) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   173
            return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   174
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   175
        // nothing to compare yet, defer the check to when sigParams is set
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   176
        if (sigParams == null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   177
            return true;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   178
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   179
        PSSParameterSpec pssKeyParams = (PSSParameterSpec) keyParams;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   180
        // first check the salt length requirement
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   181
        if (pssKeyParams.getSaltLength() > sigParams.getSaltLength()) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   182
            return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   183
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   184
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   185
        // compare equality of the rest of fields based on DER encoding
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   186
        PSSParameterSpec keyParams2 =
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   187
            new PSSParameterSpec(pssKeyParams.getDigestAlgorithm(),
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   188
                    pssKeyParams.getMGFAlgorithm(),
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   189
                    pssKeyParams.getMGFParameters(),
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   190
                    sigParams.getSaltLength(),
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   191
                    pssKeyParams.getTrailerField());
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   192
        PSSParameters ap = new PSSParameters();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   193
        // skip the JCA overhead
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   194
        try {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   195
            ap.engineInit(keyParams2);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   196
            byte[] encoded = ap.engineGetEncoded();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   197
            ap.engineInit(sigParams);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   198
            byte[] encoded2 = ap.engineGetEncoded();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   199
            return Arrays.equals(encoded, encoded2);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   200
        } catch (Exception e) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   201
            if (DEBUG) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   202
                e.printStackTrace();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   203
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   204
            return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   205
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   206
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   207
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   208
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   209
     * Validate the specified RSAKey and its associated parameters against
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   210
     * internal signature parameters.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   211
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   212
    private RSAKey isValid(RSAKey rsaKey) throws InvalidKeyException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   213
        try {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   214
            AlgorithmParameterSpec keyParams = rsaKey.getParams();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   215
            // validate key parameters
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   216
            if (!isCompatible(rsaKey.getParams(), this.sigParams)) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   217
                throw new InvalidKeyException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   218
                    ("Key contains incompatible PSS parameter values");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   219
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   220
            // validate key length
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   221
            if (this.sigParams != null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   222
                Integer hLen =
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   223
                    DIGEST_LENGTHS.get(this.sigParams.getDigestAlgorithm());
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   224
                if (hLen == null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   225
                    throw new ProviderException("Unsupported digest algo: " +
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   226
                        this.sigParams.getDigestAlgorithm());
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   227
                }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   228
                checkKeyLength(rsaKey, hLen, this.sigParams.getSaltLength());
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   229
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   230
            return rsaKey;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   231
        } catch (SignatureException e) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   232
            throw new InvalidKeyException(e);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   233
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   234
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   235
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   236
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   237
     * Validate the specified Signature PSS parameters.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   238
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   239
    private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   240
            throws InvalidAlgorithmParameterException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   241
        if (p == null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   242
            throw new InvalidAlgorithmParameterException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   243
                ("Parameters cannot be null");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   244
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   245
        if (!(p instanceof PSSParameterSpec)) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   246
            throw new InvalidAlgorithmParameterException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   247
                ("parameters must be type PSSParameterSpec");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   248
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   249
        // no need to validate again if same as current signature parameters
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   250
        PSSParameterSpec params = (PSSParameterSpec) p;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   251
        if (params == this.sigParams) return params;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   252
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   253
        RSAKey key = (this.privKey == null? this.pubKey : this.privKey);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   254
        // check against keyParams if set
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   255
        if (key != null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   256
            if (!isCompatible(key.getParams(), params)) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   257
                throw new InvalidAlgorithmParameterException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   258
                    ("Signature parameters does not match key parameters");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   259
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   260
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   261
        // now sanity check the parameter values
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   262
        if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   263
            throw new InvalidAlgorithmParameterException("Only supports MGF1");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   264
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   265
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   266
        if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   267
            throw new InvalidAlgorithmParameterException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   268
                ("Only supports TrailerFieldBC(1)");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   269
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   270
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   271
        String digestAlgo = params.getDigestAlgorithm();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   272
        // check key length again
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   273
        if (key != null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   274
            try {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   275
                int hLen = DIGEST_LENGTHS.get(digestAlgo);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   276
                checkKeyLength(key, hLen, params.getSaltLength());
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   277
            } catch (SignatureException e) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   278
                throw new InvalidAlgorithmParameterException(e);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   279
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   280
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   281
        return params;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   282
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   283
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   284
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   285
     * Ensure the object is initialized with key and parameters and
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   286
     * reset digest
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   287
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   288
    private void ensureInit() throws SignatureException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   289
        RSAKey key = (this.privKey == null? this.pubKey : this.privKey);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   290
        if (key == null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   291
            throw new SignatureException("Missing key");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   292
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   293
        if (this.sigParams == null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   294
            // Parameters are required for signature verification
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   295
            throw new SignatureException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   296
                ("Parameters required for RSASSA-PSS signatures");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   297
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   298
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   299
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   300
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   301
     * Utility method for checking key length against digest length and
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   302
     * salt length
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   303
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   304
    private static void checkKeyLength(RSAKey key, int digestLen,
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   305
            int saltLen) throws SignatureException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   306
        if (key != null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   307
            int keyLength = getKeyLengthInBits(key) >> 3;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   308
            int minLength = Math.addExact(Math.addExact(digestLen, saltLen), 2);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   309
            if (keyLength < minLength) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   310
                throw new SignatureException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   311
                    ("Key is too short, need min " + minLength);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   312
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   313
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   314
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   315
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   316
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   317
     * Reset the message digest if it is not already reset.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   318
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   319
    private void resetDigest() {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   320
        if (digestReset == false) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   321
            this.md.reset();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   322
            digestReset = true;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   323
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   324
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   325
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   326
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   327
     * Return the message digest value.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   328
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   329
    private byte[] getDigestValue() {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   330
        digestReset = true;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   331
        return this.md.digest();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   332
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   333
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   334
    // update the signature with the plaintext data. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   335
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   336
    protected void engineUpdate(byte b) throws SignatureException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   337
        ensureInit();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   338
        this.md.update(b);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   339
        digestReset = false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   340
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   341
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   342
    // update the signature with the plaintext data. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   343
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   344
    protected void engineUpdate(byte[] b, int off, int len)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   345
            throws SignatureException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   346
        ensureInit();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   347
        this.md.update(b, off, len);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   348
        digestReset = false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   349
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   350
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   351
    // update the signature with the plaintext data. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   352
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   353
    protected void engineUpdate(ByteBuffer b) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   354
        try {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   355
            ensureInit();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   356
        } catch (SignatureException se) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   357
            // hack for working around API bug
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   358
            throw new RuntimeException(se.getMessage());
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   359
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   360
        this.md.update(b);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   361
        digestReset = false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   362
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   363
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   364
    // sign the data and return the signature. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   365
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   366
    protected byte[] engineSign() throws SignatureException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   367
        ensureInit();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   368
        byte[] mHash = getDigestValue();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   369
        try {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   370
            byte[] encoded = encodeSignature(mHash);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   371
            byte[] encrypted = RSACore.rsa(encoded, privKey, true);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   372
            return encrypted;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   373
        } catch (GeneralSecurityException e) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   374
            throw new SignatureException("Could not sign data", e);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   375
        } catch (IOException e) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   376
            throw new SignatureException("Could not encode data", e);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   377
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   378
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   379
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   380
    // verify the data and return the result. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   381
    // should be reset to the state after engineInitVerify call.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   382
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   383
    protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   384
        ensureInit();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   385
        try {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   386
            if (sigBytes.length != RSACore.getByteLength(this.pubKey)) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   387
                throw new SignatureException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   388
                    ("Signature length not correct: got "
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   389
                    + sigBytes.length + " but was expecting "
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   390
                    + RSACore.getByteLength(this.pubKey));
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   391
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   392
            byte[] mHash = getDigestValue();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   393
            byte[] decrypted = RSACore.rsa(sigBytes, this.pubKey);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   394
            return decodeSignature(mHash, decrypted);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   395
        } catch (javax.crypto.BadPaddingException e) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   396
            // occurs if the app has used the wrong RSA public key
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   397
            // or if sigBytes is invalid
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   398
            // return false rather than propagating the exception for
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   399
            // compatibility/ease of use
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   400
            return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   401
        } catch (IOException e) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   402
            throw new SignatureException("Signature encoding error", e);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   403
        } finally {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   404
            resetDigest();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   405
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   406
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   407
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   408
    // return the modulus length in bits
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   409
    private static int getKeyLengthInBits(RSAKey k) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   410
        if (k != null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   411
            return k.getModulus().bitLength();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   412
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   413
        return -1;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   414
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   415
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   416
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   417
     * Encode the digest 'mHash', return the to-be-signed data.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   418
     * Also used by the PKCS#11 provider.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   419
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   420
    private byte[] encodeSignature(byte[] mHash)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   421
        throws IOException, DigestException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   422
        AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   423
        String mgfDigestAlgo;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   424
        if (mgfParams != null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   425
            mgfDigestAlgo =
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   426
                ((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   427
        } else {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   428
            mgfDigestAlgo = this.md.getAlgorithm();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   429
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   430
        try {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   431
            int emBits = getKeyLengthInBits(this.privKey) - 1;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   432
            int emLen =(emBits + 7) >> 3;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   433
            int hLen = this.md.getDigestLength();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   434
            int dbLen = emLen - hLen - 1;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   435
            int sLen = this.sigParams.getSaltLength();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   436
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   437
            // maps DB into the corresponding region of EM and
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   438
            // stores its bytes directly into EM
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   439
            byte[] em = new byte[emLen];
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   440
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   441
            // step7 and some of step8
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   442
            em[dbLen - sLen - 1] = (byte) 1; // set DB's padding2 into EM
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   443
            em[em.length - 1] = (byte) 0xBC; // set trailer field of EM
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   444
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   445
            if (!digestReset) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   446
                throw new ProviderException("Digest should be reset");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   447
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   448
            // step5: generates M' using padding1, mHash, and salt
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   449
            this.md.update(EIGHT_BYTES_OF_ZEROS);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   450
            digestReset = false; // mark digest as it now has data
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   451
            this.md.update(mHash);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   452
            if (sLen != 0) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   453
                // step4: generate random salt
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   454
                byte[] salt = new byte[sLen];
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   455
                this.random.nextBytes(salt);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   456
                this.md.update(salt);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   457
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   458
                // step8: set DB's salt into EM
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   459
                System.arraycopy(salt, 0, em, dbLen - sLen, sLen);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   460
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   461
            // step6: generate H using M'
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   462
            this.md.digest(em, dbLen, hLen); // set H field of EM
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   463
            digestReset = true;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   464
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   465
            // step7 and 8 are already covered by the code which setting up
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   466
            // EM as above
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   467
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   468
            // step9 and 10: feed H into MGF and xor with DB in EM
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   469
            MGF1 mgf1 = new MGF1(mgfDigestAlgo);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   470
            mgf1.generateAndXor(em, dbLen, hLen, dbLen, em, 0);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   471
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   472
            // step11: set the leftmost (8emLen - emBits) bits of the leftmost
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   473
            // octet to 0
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   474
            int numZeroBits = (emLen << 3) - emBits;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   475
            if (numZeroBits != 0) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   476
                byte MASK = (byte) (0xff >>> numZeroBits);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   477
                em[0] = (byte) (em[0] & MASK);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   478
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   479
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   480
            // step12: em should now holds maskedDB || hash h || 0xBC
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   481
            return em;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   482
        } catch (NoSuchAlgorithmException e) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   483
            throw new IOException(e.toString());
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   484
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   485
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   486
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   487
    /**
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   488
     * Decode the signature data. Verify that the object identifier matches
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   489
     * and return the message digest.
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   490
     */
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   491
    private boolean decodeSignature(byte[] mHash, byte[] em)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   492
            throws IOException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   493
        int hLen = mHash.length;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   494
        int sLen = this.sigParams.getSaltLength();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   495
        int emLen = em.length;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   496
        int emBits = getKeyLengthInBits(this.pubKey) - 1;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   497
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   498
        // step3
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   499
        if (emLen < (hLen + sLen + 2)) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   500
            return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   501
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   502
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   503
        // step4
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   504
        if (em[emLen - 1] != (byte) 0xBC) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   505
            return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   506
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   507
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   508
        // step6: check if the leftmost (8emLen - emBits) bits of the leftmost
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   509
        // octet are 0
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   510
        int numZeroBits = (emLen << 3) - emBits;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   511
        if (numZeroBits != 0) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   512
            byte MASK = (byte) (0xff << (8 - numZeroBits));
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   513
            if ((em[0] & MASK) != 0) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   514
                return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   515
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   516
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   517
        String mgfDigestAlgo;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   518
        AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   519
        if (mgfParams != null) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   520
            mgfDigestAlgo =
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   521
                ((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   522
        } else {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   523
            mgfDigestAlgo = this.md.getAlgorithm();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   524
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   525
        // step 7 and 8
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   526
        int dbLen = emLen - hLen - 1;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   527
        try {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   528
            MGF1 mgf1 = new MGF1(mgfDigestAlgo);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   529
            mgf1.generateAndXor(em, dbLen, hLen, dbLen, em, 0);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   530
        } catch (NoSuchAlgorithmException nsae) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   531
            throw new IOException(nsae.toString());
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   532
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   533
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   534
        // step9: set the leftmost (8emLen - emBits) bits of the leftmost
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   535
        //  octet to 0
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   536
        if (numZeroBits != 0) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   537
            byte MASK = (byte) (0xff >>> numZeroBits);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   538
            em[0] = (byte) (em[0] & MASK);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   539
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   540
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   541
        // step10
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   542
        int i = 0;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   543
        for (; i < dbLen - sLen - 1; i++) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   544
            if (em[i] != 0) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   545
                return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   546
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   547
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   548
        if (em[i] != 0x01) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   549
            return false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   550
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   551
        // step12 and 13
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   552
        this.md.update(EIGHT_BYTES_OF_ZEROS);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   553
        digestReset = false;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   554
        this.md.update(mHash);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   555
        if (sLen > 0) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   556
            this.md.update(em, (dbLen - sLen), sLen);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   557
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   558
        byte[] digest2 = this.md.digest();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   559
        digestReset = true;
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   560
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   561
        // step14
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   562
        byte[] digestInEM = Arrays.copyOfRange(em, dbLen, emLen - 1);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   563
        return MessageDigest.isEqual(digest2, digestInEM);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   564
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   565
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   566
    // set parameter, not supported. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   567
    @Deprecated
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   568
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   569
    protected void engineSetParameter(String param, Object value)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   570
            throws InvalidParameterException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   571
        throw new UnsupportedOperationException("setParameter() not supported");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   572
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   573
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   574
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   575
    protected void engineSetParameter(AlgorithmParameterSpec params)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   576
            throws InvalidAlgorithmParameterException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   577
        this.sigParams = validateSigParams(params);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   578
        // disallow changing parameters when digest has been used
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   579
        if (!digestReset) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   580
            throw new ProviderException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   581
                ("Cannot set parameters during operations");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   582
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   583
        String newHashAlg = this.sigParams.getDigestAlgorithm();
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   584
        // re-allocate md if not yet assigned or algorithm changed
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   585
        if ((this.md == null) ||
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   586
            !(this.md.getAlgorithm().equalsIgnoreCase(newHashAlg))) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   587
            try {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   588
                this.md = MessageDigest.getInstance(newHashAlg);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   589
            } catch (NoSuchAlgorithmException nsae) {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   590
                // should not happen as we pick default digest algorithm
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   591
                throw new InvalidAlgorithmParameterException
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   592
                    ("Unsupported digest algorithm " +
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   593
                     newHashAlg, nsae);
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   594
            }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   595
        }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   596
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   597
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   598
    // get parameter, not supported. See JCA doc
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   599
    @Deprecated
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   600
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   601
    protected Object engineGetParameter(String param)
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   602
            throws InvalidParameterException {
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   603
        throw new UnsupportedOperationException("getParameter() not supported");
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   604
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   605
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   606
    @Override
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   607
    protected AlgorithmParameters engineGetParameters() {
51229
17b7d7034e8e 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized
valeriep
parents: 50715
diff changeset
   608
        AlgorithmParameters ap = null;
17b7d7034e8e 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized
valeriep
parents: 50715
diff changeset
   609
        if (this.sigParams != null) {
17b7d7034e8e 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized
valeriep
parents: 50715
diff changeset
   610
            try {
17b7d7034e8e 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized
valeriep
parents: 50715
diff changeset
   611
                ap = AlgorithmParameters.getInstance("RSASSA-PSS");
17b7d7034e8e 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized
valeriep
parents: 50715
diff changeset
   612
                ap.init(this.sigParams);
17b7d7034e8e 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized
valeriep
parents: 50715
diff changeset
   613
            } catch (GeneralSecurityException gse) {
17b7d7034e8e 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized
valeriep
parents: 50715
diff changeset
   614
                throw new ProviderException(gse.getMessage());
17b7d7034e8e 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized
valeriep
parents: 50715
diff changeset
   615
            }
50204
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   616
        }
51229
17b7d7034e8e 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized
valeriep
parents: 50715
diff changeset
   617
        return ap;
50204
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   618
    }
3195a713e24d 8146293: Add support for RSASSA-PSS Signature algorithm
valeriep
parents:
diff changeset
   619
}