jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java
changeset 12201 d77ed23f4992
parent 5506 202f599c92aa
child 16080 0e6266b88242
equal deleted inserted replaced
12200:d935c2f4aeae 12201:d77ed23f4992
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    31 import java.security.InvalidAlgorithmParameterException;
    31 import java.security.InvalidAlgorithmParameterException;
    32 import java.security.InvalidKeyException;
    32 import java.security.InvalidKeyException;
    33 import java.security.Key;
    33 import java.security.Key;
    34 import java.security.NoSuchAlgorithmException;
    34 import java.security.NoSuchAlgorithmException;
    35 import java.security.SecureRandom;
    35 import java.security.SecureRandom;
       
    36 import java.security.ProviderException;
    36 import java.security.spec.AlgorithmParameterSpec;
    37 import java.security.spec.AlgorithmParameterSpec;
    37 import java.security.spec.InvalidKeySpecException;
    38 import java.security.spec.InvalidKeySpecException;
    38 import javax.crypto.KeyAgreementSpi;
    39 import javax.crypto.KeyAgreementSpi;
    39 import javax.crypto.ShortBufferException;
    40 import javax.crypto.ShortBufferException;
    40 import javax.crypto.SecretKey;
    41 import javax.crypto.SecretKey;
   232      * completed yet
   233      * completed yet
   233      */
   234      */
   234     protected byte[] engineGenerateSecret()
   235     protected byte[] engineGenerateSecret()
   235         throws IllegalStateException
   236         throws IllegalStateException
   236     {
   237     {
   237         if (generateSecret == false) {
   238         int expectedLen = (init_p.bitLength() + 7) >>> 3;
   238             throw new IllegalStateException
   239         byte[] result = new byte[expectedLen];
   239                 ("Key agreement has not been completed yet");
   240         try {
   240         }
   241             engineGenerateSecret(result, 0);
   241 
   242         } catch (ShortBufferException sbe) {
   242         // Reset the key agreement here (in case anything goes wrong)
   243             // should never happen since length are identical
   243         generateSecret = false;
   244         }
   244 
   245         return result;
   245         // get the modulus
       
   246         BigInteger modulus = init_p;
       
   247 
       
   248         BigInteger tmpResult = y.modPow(x, modulus);
       
   249         byte[] secret = tmpResult.toByteArray();
       
   250 
       
   251         /*
       
   252          * BigInteger.toByteArray will sometimes put a sign byte up front, but
       
   253          * we NEVER want one.
       
   254          */
       
   255         if ((tmpResult.bitLength() % 8) == 0) {
       
   256             byte retval[] = new byte[secret.length - 1];
       
   257             System.arraycopy(secret, 1, retval, 0, retval.length);
       
   258             return retval;
       
   259         } else {
       
   260             return secret;
       
   261         }
       
   262     }
   246     }
   263 
   247 
   264     /**
   248     /**
   265      * Generates the shared secret, and places it into the buffer
   249      * Generates the shared secret, and places it into the buffer
   266      * <code>sharedSecret</code>, beginning at <code>offset</code>.
   250      * <code>sharedSecret</code>, beginning at <code>offset</code>.
   299             throw new ShortBufferException
   283             throw new ShortBufferException
   300                 ("No buffer provided for shared secret");
   284                 ("No buffer provided for shared secret");
   301         }
   285         }
   302 
   286 
   303         BigInteger modulus = init_p;
   287         BigInteger modulus = init_p;
       
   288         int expectedLen = (modulus.bitLength() + 7) >>> 3;
       
   289         if ((sharedSecret.length - offset) < expectedLen) {
       
   290             throw new ShortBufferException
       
   291                     ("Buffer too short for shared secret");
       
   292         }
       
   293 
       
   294         // Reset the key agreement after checking for ShortBufferException
       
   295         // above, so user can recover w/o losing internal state
       
   296         generateSecret = false;
       
   297 
       
   298         /*
       
   299          * NOTE: BigInteger.toByteArray() returns a byte array containing
       
   300          * the two's-complement representation of this BigInteger with
       
   301          * the most significant byte is in the zeroth element. This
       
   302          * contains the minimum number of bytes required to represent
       
   303          * this BigInteger, including at least one sign bit whose value
       
   304          * is always 0.
       
   305          *
       
   306          * Keys are always positive, and the above sign bit isn't
       
   307          * actually used when representing keys.  (i.e. key = new
       
   308          * BigInteger(1, byteArray))  To obtain an array containing
       
   309          * exactly expectedLen bytes of magnitude, we strip any extra
       
   310          * leading 0's, or pad with 0's in case of a "short" secret.
       
   311          */
   304         byte[] secret = this.y.modPow(this.x, modulus).toByteArray();
   312         byte[] secret = this.y.modPow(this.x, modulus).toByteArray();
   305 
   313         if (secret.length == expectedLen) {
   306         // BigInteger.toByteArray will sometimes put a sign byte up front,
   314             System.arraycopy(secret, 0, sharedSecret, offset,
   307         // but we NEVER want one.
   315                              secret.length);
   308         if ((secret.length << 3) != modulus.bitLength()) {
   316         } else {
   309             if ((sharedSecret.length - offset) < (secret.length - 1)) {
   317             // Array too short, pad it w/ leading 0s
   310                 throw new ShortBufferException
   318             if (secret.length < expectedLen) {
   311                     ("Buffer too short for shared secret");
   319                 System.arraycopy(secret, 0, sharedSecret,
       
   320                     offset + (expectedLen - secret.length),
       
   321                     secret.length);
       
   322             } else {
       
   323                 // Array too long, check and trim off the excess
       
   324                 if ((secret.length == (expectedLen+1)) && secret[0] == 0) {
       
   325                     // ignore the leading sign byte
       
   326                     System.arraycopy(secret, 1, sharedSecret, offset, expectedLen);
       
   327                 } else {
       
   328                     throw new ProviderException("Generated secret is out-of-range");
       
   329                 }
   312             }
   330             }
   313             System.arraycopy(secret, 1, sharedSecret, offset,
   331         }
   314                              secret.length - 1);
   332         return expectedLen;
   315 
       
   316             // Reset the key agreement here (not earlier!), so that people
       
   317             // can recover from ShortBufferException above without losing
       
   318             // internal state
       
   319             generateSecret = false;
       
   320 
       
   321             return secret.length - 1;
       
   322 
       
   323         } else {
       
   324             if ((sharedSecret.length - offset) < secret.length) {
       
   325                 throw new ShortBufferException
       
   326                     ("Buffer too short to hold shared secret");
       
   327             }
       
   328             System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
       
   329 
       
   330             // Reset the key agreement here (not earlier!), so that people
       
   331             // can recover from ShortBufferException above without losing
       
   332             // internal state
       
   333             generateSecret = false;
       
   334 
       
   335             return secret.length;
       
   336         }
       
   337     }
   333     }
   338 
   334 
   339     /**
   335     /**
   340      * Creates the shared secret and returns it as a secret key object
   336      * Creates the shared secret and returns it as a secret key object
   341      * of the requested algorithm type.
   337      * of the requested algorithm type.