Save This Page
Home » openjdk-7 » com.sun.crypto » provider » [javadoc | source]
    1   /*
    2    * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package com.sun.crypto.provider;
   27   
   28   import java.math.BigInteger;
   29   import java.util;
   30   import java.io;
   31   import sun.security.util;
   32   import sun.security.x509;
   33   import java.security.AlgorithmParametersSpi;
   34   import java.security.NoSuchAlgorithmException;
   35   import java.security.spec.AlgorithmParameterSpec;
   36   import java.security.spec.InvalidParameterSpecException;
   37   import java.security.spec.MGF1ParameterSpec;
   38   import javax.crypto.spec.PSource;
   39   import javax.crypto.spec.OAEPParameterSpec;
   40   
   41   /**
   42    * This class implements the OAEP parameters used with the RSA
   43    * algorithm in OAEP padding. Here is its ASN.1 definition:
   44    * RSAES-OAEP-params ::= SEQUENCE {
   45    *   hashAlgorithm      [0] HashAlgorithm     DEFAULT sha1,
   46    *   maskGenAlgorithm   [1] MaskGenAlgorithm  DEFAULT mgf1SHA1,
   47    *   pSourceAlgorithm   [2] PSourceAlgorithm  DEFAULT pSpecifiedEmpty
   48    * }
   49    *
   50    * @author Valerie Peng
   51    *
   52    */
   53   
   54   public final class OAEPParameters extends AlgorithmParametersSpi {
   55   
   56       private String mdName;
   57       private MGF1ParameterSpec mgfSpec;
   58       private byte[] p;
   59       private static ObjectIdentifier OID_MGF1;
   60       private static ObjectIdentifier OID_PSpecified;
   61   
   62       static {
   63           try {
   64               OID_MGF1 = new ObjectIdentifier(new int[] {1,2,840,113549,1,1,8});
   65           } catch (IOException ioe) {
   66               // should not happen
   67               OID_MGF1 = null;
   68           }
   69           try {
   70               OID_PSpecified =
   71                   new ObjectIdentifier(new int[] {1,2,840,113549,1,1,9});
   72           } catch (IOException ioe) {
   73               // should not happen
   74               OID_PSpecified = null;
   75           }
   76       }
   77   
   78       public OAEPParameters() {
   79       }
   80   
   81       protected void engineInit(AlgorithmParameterSpec paramSpec)
   82           throws InvalidParameterSpecException {
   83           if (!(paramSpec instanceof OAEPParameterSpec)) {
   84               throw new InvalidParameterSpecException
   85                   ("Inappropriate parameter specification");
   86           }
   87           OAEPParameterSpec spec = (OAEPParameterSpec) paramSpec;
   88           mdName = spec.getDigestAlgorithm();
   89           String mgfName = spec.getMGFAlgorithm();
   90           if (!mgfName.equalsIgnoreCase("MGF1")) {
   91               throw new InvalidParameterSpecException("Unsupported mgf " +
   92                   mgfName + "; MGF1 only");
   93           }
   94           AlgorithmParameterSpec mgfSpec = spec.getMGFParameters();
   95           if (!(mgfSpec instanceof MGF1ParameterSpec)) {
   96               throw new InvalidParameterSpecException("Inappropriate mgf " +
   97                   "parameters; non-null MGF1ParameterSpec only");
   98           }
   99           this.mgfSpec = (MGF1ParameterSpec) mgfSpec;
  100           PSource pSrc = spec.getPSource();
  101           if (pSrc.getAlgorithm().equals("PSpecified")) {
  102               p = ((PSource.PSpecified) pSrc).getValue();
  103           } else {
  104               throw new InvalidParameterSpecException("Unsupported pSource " +
  105                   pSrc.getAlgorithm() + "; PSpecified only");
  106           }
  107       }
  108   
  109       private static String convertToStandardName(String internalName) {
  110           if (internalName.equals("SHA")) {
  111               return "SHA-1";
  112           } else if (internalName.equals("SHA256")) {
  113               return "SHA-256";
  114           } else if (internalName.equals("SHA384")) {
  115               return "SHA-384";
  116           } else if (internalName.equals("SHA512")) {
  117               return "SHA-512";
  118           } else {
  119               return internalName;
  120           }
  121       }
  122   
  123       protected void engineInit(byte[] encoded)
  124           throws IOException {
  125           DerInputStream der = new DerInputStream(encoded);
  126           mdName = "SHA-1";
  127           mgfSpec = MGF1ParameterSpec.SHA1;
  128           p = new byte[0];
  129           DerValue[] datum = der.getSequence(3);
  130           for (int i=0; i<datum.length; i++) {
  131               DerValue data = datum[i];
  132               if (data.isContextSpecific((byte) 0x00)) {
  133                   // hash algid
  134                   mdName = convertToStandardName(AlgorithmId.parse
  135                       (data.data.getDerValue()).getName());
  136               } else if (data.isContextSpecific((byte) 0x01)) {
  137                   // mgf algid
  138                   AlgorithmId val = AlgorithmId.parse(data.data.getDerValue());
  139                   if (!val.getOID().equals((Object) OID_MGF1)) {
  140                       throw new IOException("Only MGF1 mgf is supported");
  141                   }
  142                   AlgorithmId params = AlgorithmId.parse(
  143                       new DerValue(val.getEncodedParams()));
  144                   String mgfDigestName = convertToStandardName(params.getName());
  145                   if (mgfDigestName.equals("SHA-1")) {
  146                       mgfSpec = MGF1ParameterSpec.SHA1;
  147                   } else if (mgfDigestName.equals("SHA-256")) {
  148                       mgfSpec = MGF1ParameterSpec.SHA256;
  149                   } else if (mgfDigestName.equals("SHA-384")) {
  150                       mgfSpec = MGF1ParameterSpec.SHA384;
  151                   } else if (mgfDigestName.equals("SHA-512")) {
  152                       mgfSpec = MGF1ParameterSpec.SHA512;
  153                   } else {
  154                       throw new IOException(
  155                           "Unrecognized message digest algorithm");
  156                   }
  157               } else if (data.isContextSpecific((byte) 0x02)) {
  158                   // pSource algid
  159                   AlgorithmId val = AlgorithmId.parse(data.data.getDerValue());
  160                   if (!val.getOID().equals((Object) OID_PSpecified)) {
  161                       throw new IOException("Wrong OID for pSpecified");
  162                   }
  163                   DerInputStream dis = new DerInputStream(val.getEncodedParams());
  164                   p = dis.getOctetString();
  165                   if (dis.available() != 0) {
  166                       throw new IOException("Extra data for pSpecified");
  167                   }
  168               } else {
  169                   throw new IOException("Invalid encoded OAEPParameters");
  170               }
  171           }
  172       }
  173   
  174       protected void engineInit(byte[] encoded, String decodingMethod)
  175           throws IOException {
  176           if ((decodingMethod != null) &&
  177               (!decodingMethod.equalsIgnoreCase("ASN.1"))) {
  178               throw new IllegalArgumentException("Only support ASN.1 format");
  179           }
  180           engineInit(encoded);
  181       }
  182   
  183       protected AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec)
  184           throws InvalidParameterSpecException {
  185           if (OAEPParameterSpec.class.isAssignableFrom(paramSpec)) {
  186               return new OAEPParameterSpec(mdName, "MGF1", mgfSpec,
  187                   new PSource.PSpecified(p));
  188           } else {
  189               throw new InvalidParameterSpecException
  190                   ("Inappropriate parameter specification");
  191           }
  192       }
  193   
  194       protected byte[] engineGetEncoded() throws IOException {
  195           DerOutputStream tmp = new DerOutputStream();
  196           DerOutputStream tmp2, tmp3;
  197   
  198           // MD
  199           AlgorithmId mdAlgId;
  200           try {
  201               mdAlgId = AlgorithmId.get(mdName);
  202           } catch (NoSuchAlgorithmException nsae) {
  203               throw new IOException("AlgorithmId " + mdName +
  204                                     " impl not found");
  205           }
  206           tmp2 = new DerOutputStream();
  207           mdAlgId.derEncode(tmp2);
  208           tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0),
  209                         tmp2);
  210   
  211           // MGF
  212           tmp2 = new DerOutputStream();
  213           tmp2.putOID(OID_MGF1);
  214           AlgorithmId mgfDigestId;
  215           try {
  216               mgfDigestId = AlgorithmId.get(mgfSpec.getDigestAlgorithm());
  217           } catch (NoSuchAlgorithmException nase) {
  218               throw new IOException("AlgorithmId " +
  219                       mgfSpec.getDigestAlgorithm() + " impl not found");
  220           }
  221           mgfDigestId.encode(tmp2);
  222           tmp3 = new DerOutputStream();
  223           tmp3.write(DerValue.tag_Sequence, tmp2);
  224           tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)1),
  225                     tmp3);
  226   
  227           // PSource
  228           tmp2 = new DerOutputStream();
  229           tmp2.putOID(OID_PSpecified);
  230           tmp2.putOctetString(p);
  231           tmp3 = new DerOutputStream();
  232           tmp3.write(DerValue.tag_Sequence, tmp2);
  233           tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)2),
  234                     tmp3);
  235   
  236           // Put all together under a SEQUENCE tag
  237           DerOutputStream out = new DerOutputStream();
  238           out.write(DerValue.tag_Sequence, tmp);
  239           return out.toByteArray();
  240       }
  241   
  242       protected byte[] engineGetEncoded(String encodingMethod)
  243           throws IOException {
  244           if ((encodingMethod != null) &&
  245               (!encodingMethod.equalsIgnoreCase("ASN.1"))) {
  246               throw new IllegalArgumentException("Only support ASN.1 format");
  247           }
  248           return engineGetEncoded();
  249       }
  250   
  251       protected String engineToString() {
  252           StringBuffer sb = new StringBuffer();
  253           sb.append("MD: " + mdName + "\n");
  254           sb.append("MGF: MGF1" + mgfSpec.getDigestAlgorithm() + "\n");
  255           sb.append("PSource: PSpecified " +
  256               (p.length==0? "":Debug.toHexString(new BigInteger(p))) + "\n");
  257           return sb.toString();
  258       }
  259   }

Save This Page
Home » openjdk-7 » com.sun.crypto » provider » [javadoc | source]