Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8193887

Allow user provided ObjectInputFilter in SealedObject and SignedObject

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P3
    • Resolution: Approved
    • Fix Version/s: 12
    • Component/s: security-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      source
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      Minor source compatibility risk if existing subclasses already declared methods whose signatures conflict with the added methods.
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      SealedObject and SignedObject store an object in its serialized form. It will be return by one of the getObject() methods.

      Problem

      Since the ObjectInputStream to read the object is not exposed to the caller, there is no way to set an ObjectInputFilter on it.

      Solution

      Provide overloaded getObject() methods with an ObjectInputFilter parameter.

      Specification

      New methods for SignedObject:

      /**
       * Retrieves the encapsulated object.
       * The encapsulated object is deserialized with an
       * {@link ObjectInputFilter} before it is returned.
       *
       * @param filter the filter used to check the serialized data
       *
       * @return the encapsulated object
       *
       * @throws ClassNotFoundException if the class of a serialized object
       *      cannot be found
       * @throws IOException if an I/O error occurs during deserialization
       * @throws NullPointerException if {@code filter} is null
       * @throws SecurityException if a security manager is enabled and the
       *      {@code SerializablePermission("serialFilter")} has not been granted
       *
       * @since 12
       */
      public Object getObject(ObjectInputFilter filter)
              throws IOException, ClassNotFoundException;

      New methods for SealedObject:

      /**
       * Retrieves the original (encapsulated) object.
       *
       * <p>The encapsulated object is unsealed (using the given Cipher,
       * assuming that the Cipher is already properly initialized) and
       * deserialized with the given {@link ObjectInputFilter},
       * before it is returned.
       *
       * @param c the cipher used to unseal the object
       * @param filter the filter used to check the decrypted serialized data
       *
       * @return the original object
       *
       * @throws BadPaddingException if the given cipher has been
       *      initialized for decryption, and padding has been specified, but
       *      the input data does not have proper expected padding bytes
       * @throws ClassNotFoundException if the class of a serialized object
       *      cannot be found
       * @throws IllegalBlockSizeException if the given cipher is a block
       *      cipher, no padding has been requested, and the total input length
       *      is not a multiple of the cipher's block size
       * @throws IOException if an I/O error occurs during deserialization
       * @throws NullPointerException if the given cipher or filter is null
       * @throws SecurityException if a security manager is enabled and the
       *      {@code SerializablePermission("serialFilter")} has not been granted
       *
       * @since 12
       */
      public final Object getObject(Cipher c, ObjectInputFilter filter)
          throws IOException, ClassNotFoundException, IllegalBlockSizeException,
              BadPaddingException;
      
      /**
       * Retrieves the original (encapsulated) object.
       *
       * <p>This method creates a cipher for the algorithm that had been used in
       * the sealing operation.
       * If the default provider package provides an implementation of that
       * algorithm, an instance of Cipher containing that implementation is used.
       * If the algorithm is not available in the default package, other
       * packages are searched.
       * The Cipher object is initialized for decryption, using the given
       * <code>key</code> and the parameters (if any) that had been used in the
       * sealing operation.
       *
       * <p>The encapsulated object is unsealed and deserialized with the given
       * {@link ObjectInputFilter}, before it is returned.
       *
       * @param key the key used to unseal the object
       * @param filter the filter used to check the decrypted serialized data
       *
       * @return the original object
       *
       * @throws ClassNotFoundException if the class of a serialized object
       *      cannot be found
       * @throws InvalidKeyException if the given key cannot be used to unseal
       *      the object (e.g., it has the wrong algorithm)
       * @throws IOException if an I/O error occurs during deserialization
       * @throws NoSuchAlgorithmException if the algorithm to unseal the
       *      object is not available
       * @throws NullPointerException if {@code key} or {@code filter} is null
       * @throws SecurityException if a security manager is enabled and the
       *      {@code SerializablePermission("serialFilter")} has not been granted
       *
       * @since 12
       */
      public final Object getObject(Key key, ObjectInputFilter filter)
              throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
              InvalidKeyException;
      
      /**
       * Retrieves the original (encapsulated) object.
       *
       * <p>This method creates a cipher for the algorithm that had been used in
       * the sealing operation, using an implementation of that algorithm from
       * the given <code>provider</code>.
       * The Cipher object is initialized for decryption, using the given
       * <code>key</code> and the parameters (if any) that had been used in the
       * sealing operation.
       *
       * <p>The encapsulated object is unsealed and deserialized with the given
       * {@link ObjectInputFilter}, before it is returned.
       *
       * @param key the key used to unseal the object
       * @param provider the name of the provider of the algorithm to unseal
       *      the object
       * @param filter the filter used to check the decrypted serialized data
       *
       * @return the original object
       *
       * @throws ClassNotFoundException if the class of a serialized object
       *      cannot be found
       * @throws IllegalArgumentException if the given provider is null or empty
       * @throws InvalidKeyException if the given key cannot be used to unseal
       *      the object (e.g., it has the wrong algorithm)
       * @throws IOException if an I/O error occurs during deserialization
       * @throws NoSuchAlgorithmException if the algorithm to unseal the
       *      object is not available
       * @throws NoSuchProviderException if the given provider is not configured
       * @throws NullPointerException if {@code key} or {@code filter} is null
       * @throws SecurityException if a security manager is enabled and the
       *      {@code SerializablePermission("serialFilter")} has not been granted
       *
       * @since 12
       */
      public final Object getObject(Key key, String provider, ObjectInputFilter filter)
              throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
              NoSuchProviderException, InvalidKeyException;

      Each of the methods above is based on an existing method with these changes:

      1. An additional ObjectInputFilter parameter
      2. "with the given ObjectInputFilter" added in spec
      3. @param for the new parameter
      4. A new @throws SecurityException
      5. A new (or merged) @throws NullPointerException for the new parameter

      Besides the new methods added, these additional spec changes are proposed:

      Remove the following paragraphs in the class spec of SignedObject. The SignedObject class uses an existing Signature object while signing or verifying and never creates one itself, and therefore does not need to know about signature algorithm or provider name at all.

      - * <p> The signature algorithm can be, among others, the NIST standard
      - * DSA, using DSA and SHA-256.  The algorithm is specified using the
      - * same convention as that for signatures. The DSA algorithm using the
      - * SHA-256 message digest algorithm can be specified, for example, as
      - * "SHA256withDSA".  In the case of
      - * RSA the signing algorithm could be specified as, for example,
      - * "SHA256withRSA".  The algorithm name must be
      - * specified, as there is no default.
      - *
      - * <p> The name of the Cryptography Package Provider is designated
      - * also by the Signature parameter to the constructor and the
      - * {@code verify} method.  If the provider is not
      - * specified, the default provider is used.  Each installation can
      - * be configured to use a particular provider as default.

      Make the following change to all exising getObject methods of SignedObject and SealedObject. The original spec has the same words for two different exception types. The new spec is copied from ObjectInputStream::readObject. It is also the spec used by the newly added methods.

      -     * @exception IOException if an error occurs during de-serialization
      -     * @exception ClassNotFoundException if an error occurs during
      -     * de-serialization
      +     * @throws ClassNotFoundException if the class of a serialized object
      +     *      cannot be found
      +     * @throws IOException if an I/O error occurs during deserialization

      2018-8-15 updates

      Make this change in class spec of SignedObject:

        * if (so.verify(publickey, verificationEngine))
        *     try {
      - *         Object myobj = so.getObject();
      + *         ObjectInputFilter myfilter = ...;
      + *         Object myobj = so.getObject(myfilter);
        *     } catch (java.lang.ClassNotFoundException e) {};
        * }</pre>
        *
      + * In this example, an {@link ObjectInputFilter} is used during
      + * deserialization of the original object. If {@link #getObject()} is
      + * called, the {@link ObjectInputFilter.Config#getSerialFilter()
      + * system filter} is used instead.
      + *

      Add this paragragh in class spec of SealedObject after the descrption of 2 kinds of getObject methods:

      + * Both methods have overloaded forms that accept an {@link ObjectInputFilter}
      + * parameter, which will be used during deserialization of the original object.
      + * If a {@code getObject} method without a {@code ObjectInputFilter} parameter
      + * is called, the {@link ObjectInputFilter.Config#getSerialFilter()
      + * system filter} is used instead.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                weijun Weijun Wang
                Reporter:
                weijun Weijun Wang
                Reviewed By:
                Sean Mullan
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: