View | Details | Return to bug 26067 | Differences between
and this patch

Collapse All | Expand All

(-)IKeyPairCodec.java (-31 / +25 lines)
Lines 44-59 Link Here
44
import java.security.PublicKey;
44
import java.security.PublicKey;
45
45
46
/**
46
/**
47
 * <p>The visible methods of an object that knows how to encode and decode
47
 * The visible methods of an object that knows how to encode and decode
48
 * cryptographic asymmetric keypairs. Codecs are useful for (a) externalising
48
 * cryptographic asymmetric keypairs. Codecs are useful for (a) externalising
49
 * public and private keys for storage and on-the-wire transmission, as well as
49
 * public and private keys for storage and on-the-wire transmission, as well as
50
 * (b) re-creating their internal Java representation from external sources.</p>
50
 * (b) re-creating their internal Java representation from external sources.
51
 */
51
 */
52
public interface IKeyPairCodec
52
public interface IKeyPairCodec
53
{
53
{
54
  // Constants
55
  // -------------------------------------------------------------------------
56
57
  /** Constant identifying the <i>Raw</i> encoding format. */
54
  /** Constant identifying the <i>Raw</i> encoding format. */
58
  int RAW_FORMAT = Registry.RAW_ENCODING_ID;
55
  int RAW_FORMAT = Registry.RAW_ENCODING_ID;
59
56
Lines 69-130 Link Here
69
   */
66
   */
70
  int ASN1_FORMAT = Registry.ASN1_ENCODING_ID;
67
  int ASN1_FORMAT = Registry.ASN1_ENCODING_ID;
71
68
72
  // Method(s)
73
  // -------------------------------------------------------------------------
74
75
  /**
69
  /**
76
   * <p>Returns the unique identifier (within this library) of the format used
70
   * Returns the unique identifier (within this library) of the format used to
77
   * to externalise public and private keys.</p>
71
   * externalise public and private keys.
78
   *
72
   * 
79
   * @return the identifier of the format, the object supports.
73
   * @return the identifier of the format, the object supports.
80
   */
74
   */
81
  int getFormatID();
75
  int getFormatID();
82
76
83
  /**
77
  /**
84
   * <p>Encodes an instance of a public key for storage or transmission purposes.</p>
78
   * Encodes an instance of a public key for storage or transmission purposes.
85
   *
79
   * 
86
   * @param key the non-null key to encode.
80
   * @param key the non-null key to encode.
87
   * @return a byte sequence representing the encoding of the designated key
81
   * @return a byte sequence representing the encoding of the designated key
88
   * according to the format supported by this codec.
82
   *         according to the format supported by this codec.
89
   * @exception IllegalArgumentException if the designated key is not supported
83
   * @exception IllegalArgumentException if the designated key is not supported
90
   * by this codec.
84
   *              by this codec.
91
   */
85
   */
92
  byte[] encodePublicKey(PublicKey key);
86
  byte[] encodePublicKey(PublicKey key);
93
87
94
  /**
88
  /**
95
   * <p>Encodes an instance of a private key for storage or transmission purposes.</p>
89
   * Encodes an instance of a private key for storage or transmission purposes.
96
   *
90
   * 
97
   * @param key the non-null key to encode.
91
   * @param key the non-null key to encode.
98
   * @return a byte sequence representing the encoding of the designated key
92
   * @return a byte sequence representing the encoding of the designated key
99
   * according to the format supported by this codec.
93
   *         according to the format supported by this codec.
100
   * @exception IllegalArgumentException if the designated key is not supported
94
   * @exception IllegalArgumentException if the designated key is not supported
101
   * by this codec.
95
   *              by this codec.
102
   */
96
   */
103
  byte[] encodePrivateKey(PrivateKey key);
97
  byte[] encodePrivateKey(PrivateKey key);
104
98
105
  /**
99
  /**
106
   * <p>Decodes an instance of an external public key into its native Java
100
   * Decodes an instance of an external public key into its native Java
107
   * representation.</p>
101
   * representation.
108
   *
102
   * 
109
   * @param input the source of the externalised key to decode.
103
   * @param input the source of the externalised key to decode.
110
   * @return a concrete instance of a public key, reconstructed from the
104
   * @return a concrete instance of a public key, reconstructed from the
111
   * designated input.
105
   *         designated input.
112
   * @exception IllegalArgumentException if the designated input does not
106
   * @exception IllegalArgumentException if the designated input does not
113
   * contain a known representation of a public key for the format supported by
107
   *              contain a known representation of a public key for the format
114
   * the concrete codec.
108
   *              supported by the concrete codec.
115
   */
109
   */
116
  PublicKey decodePublicKey(byte[] input);
110
  PublicKey decodePublicKey(byte[] input);
117
111
118
  /**
112
  /**
119
   * <p>Decodes an instance of an external private key into its native Java
113
   * Decodes an instance of an external private key into its native Java
120
   * representation.</p>
114
   * representation.
121
   *
115
   * 
122
   * @param input the source of the externalised key to decode.
116
   * @param input the source of the externalised key to decode.
123
   * @return a concrete instance of a private key, reconstructed from the
117
   * @return a concrete instance of a private key, reconstructed from the
124
   * designated input.
118
   *         designated input.
125
   * @exception IllegalArgumentException if the designated input does not
119
   * @exception IllegalArgumentException if the designated input does not
126
   * contain a known representation of a private key for the format supported
120
   *              contain a known representation of a private key for the format
127
   * by the concrete codec.
121
   *              supported by the concrete codec.
128
   */
122
   */
129
  PrivateKey decodePrivateKey(byte[] input);
123
  PrivateKey decodePrivateKey(byte[] input);
130
}
124
}
(-)IKeyPairGenerator.java (-15 / +8 lines)
Lines 42-79 Link Here
42
import java.util.Map;
42
import java.util.Map;
43
43
44
/**
44
/**
45
 * The visible methods of every asymmetric keypair generator.<p>
45
 * The visible methods of every asymmetric keypair generator.
46
 */
46
 */
47
public interface IKeyPairGenerator
47
public interface IKeyPairGenerator
48
{
48
{
49
50
  // Constants
51
  // -------------------------------------------------------------------------
52
53
  // Methods
54
  // -------------------------------------------------------------------------
55
56
  /**
49
  /**
57
   * Returns the canonical name of this keypair generator.<p>
50
   * Returns the canonical name of this keypair generator.
58
   *
51
   * 
59
   * @return the canonical name of this instance.
52
   * @return the canonical name of this instance.
60
   */
53
   */
61
  String name();
54
  String name();
62
55
63
  /**
56
  /**
64
   * [Re]-initialises this instance for use with a given set of attributes.<p>
57
   * [Re]-initialises this instance for use with a given set of attributes.
65
   *
58
   * 
66
   * @param attributes a map of name/value pairs to use for setting up the
59
   * @param attributes a map of name/value pairs to use for setting up the
67
   * instance.
60
   *          instance.
68
   * @exception IllegalArgumentException if at least one of the mandatory
61
   * @exception IllegalArgumentException if at least one of the mandatory
69
   * attributes is missing or an invalid value was specified.
62
   *              attributes is missing or an invalid value was specified.
70
   */
63
   */
71
  void setup(Map attributes);
64
  void setup(Map attributes);
72
65
73
  /**
66
  /**
74
   * Generates a new keypair based on the attributes used to configure the
67
   * Generates a new keypair based on the attributes used to configure the
75
   * instance.
68
   * instance.
76
   *
69
   * 
77
   * @return a new keypair.
70
   * @return a new keypair.
78
   */
71
   */
79
  KeyPair generate();
72
  KeyPair generate();
(-)KeyPairCodecFactory.java (-2 lines)
Lines 207-216 Link Here
207
        hs.add(Registry.RSA_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME);
207
        hs.add(Registry.RSA_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME);
208
        hs.add(Registry.DH_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
208
        hs.add(Registry.DH_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
209
        hs.add(Registry.SRP_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
209
        hs.add(Registry.SRP_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
210
211
        names = Collections.unmodifiableSet(hs);
210
        names = Collections.unmodifiableSet(hs);
212
      }
211
      }
213
214
    return names;
212
    return names;
215
  }
213
  }
216
214
(-)KeyPairGeneratorFactory.java (-43 / +18 lines)
Lines 48-115 Link Here
48
import java.util.Set;
48
import java.util.Set;
49
49
50
/**
50
/**
51
 * <p>A Factory to instantiate asymmetric keypair generators.</p>
51
 * A Factory to instantiate asymmetric keypair generators.
52
 */
52
 */
53
public class KeyPairGeneratorFactory
53
public class KeyPairGeneratorFactory
54
{
54
{
55
56
  // Constants and variables
57
  // -------------------------------------------------------------------------
58
59
  // Constructor(s)
60
  // -------------------------------------------------------------------------
61
62
  /** Trivial constructor to enforce Singleton pattern. */
55
  /** Trivial constructor to enforce Singleton pattern. */
63
  private KeyPairGeneratorFactory()
56
  private KeyPairGeneratorFactory()
64
  {
57
  {
65
    super();
58
    super();
66
  }
59
  }
67
60
68
  // Class methods
69
  // -------------------------------------------------------------------------
70
71
  /**
61
  /**
72
   * <p>Returns an instance of a keypair generator given its name.</p>
62
   * Returns an instance of a keypair generator given its name.
73
   *
63
   * 
74
   * @param name the case-insensitive key generator name.
64
   * @param name the case-insensitive key generator name.
75
   * @return an instance of the keypair generator, or <code>null</code> if none
65
   * @return an instance of the keypair generator, or <code>null</code> if
76
   * found.
66
   *         none found.
77
   */
67
   */
78
  public static IKeyPairGenerator getInstance(String name)
68
  public static IKeyPairGenerator getInstance(String name)
79
  {
69
  {
80
    if (name == null)
70
    if (name == null)
81
      {
71
      return null;
82
        return null;
83
      }
84
72
85
    name = name.trim();
73
    name = name.trim();
86
    IKeyPairGenerator result = null;
74
    IKeyPairGenerator result = null;
87
    if (name.equalsIgnoreCase(Registry.DSA_KPG)
75
    if (name.equalsIgnoreCase(Registry.DSA_KPG)
88
        || name.equalsIgnoreCase(Registry.DSS_KPG))
76
        || name.equalsIgnoreCase(Registry.DSS_KPG))
89
      {
77
      result = new DSSKeyPairGenerator();
90
        result = new DSSKeyPairGenerator();
91
      }
92
    else if (name.equalsIgnoreCase(Registry.RSA_KPG))
78
    else if (name.equalsIgnoreCase(Registry.RSA_KPG))
93
      {
79
      result = new RSAKeyPairGenerator();
94
        result = new RSAKeyPairGenerator();
95
      }
96
    else if (name.equalsIgnoreCase(Registry.DH_KPG))
80
    else if (name.equalsIgnoreCase(Registry.DH_KPG))
97
      {
81
      result = makeInstance("gnu.javax.crypto.key.dh.GnuDHKeyPairGenerator");
98
        result = makeInstance ("gnu.javax.crypto.key.dh.GnuDHKeyPairGenerator");
99
      }
100
    else if (name.equalsIgnoreCase(Registry.SRP_KPG))
82
    else if (name.equalsIgnoreCase(Registry.SRP_KPG))
101
      {
83
      result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairGenerator");
102
        result = makeInstance ("gnu.javax.crypto.key.srp6.SRPKeyPairGenerator");
103
      }
104
84
105
    return result;
85
    return result;
106
  }
86
  }
107
87
108
  /**
88
  /**
109
   * <p>Returns a {@link Set} of keypair generator names supported by this
89
   * Returns a {@link Set} of keypair generator names supported by this
110
   * <i>Factory</i>. Those keypair generators may be used in conjunction with
90
   * <i>Factory</i>. Those keypair generators may be used in conjunction with
111
   * the digital signature schemes with appendix supported by this library.</p>
91
   * the digital signature schemes with appendix supported by this library.
112
   *
92
   * 
113
   * @return a {@link Set} of keypair generator names (Strings).
93
   * @return a {@link Set} of keypair generator names (Strings).
114
   */
94
   */
115
  public static final Set getNames()
95
  public static final Set getNames()
Lines 120-145 Link Here
120
    hs.add(Registry.RSA_KPG);
100
    hs.add(Registry.RSA_KPG);
121
    hs.add(Registry.DH_KPG);
101
    hs.add(Registry.DH_KPG);
122
    hs.add(Registry.SRP_KPG);
102
    hs.add(Registry.SRP_KPG);
123
124
    return Collections.unmodifiableSet(hs);
103
    return Collections.unmodifiableSet(hs);
125
  }
104
  }
126
105
127
  private static IKeyPairGenerator makeInstance (String clazz)
106
  private static IKeyPairGenerator makeInstance(String clazz)
128
  {
107
  {
129
    try
108
    try
130
      {
109
      {
131
        Class c = Class.forName (clazz);
110
        Class c = Class.forName(clazz);
132
        Constructor ctor = c.getConstructor (new Class[0]);
111
        Constructor ctor = c.getConstructor(new Class[0]);
133
        return (IKeyPairGenerator) ctor.newInstance (new Object[0]);
112
        return (IKeyPairGenerator) ctor.newInstance(new Object[0]);
134
      }
113
      }
135
    catch (Exception x)
114
    catch (Exception x)
136
      {
115
      {
137
        throw new IllegalArgumentException(
116
        throw new IllegalArgumentException(
138
            "strong crypto key pair generator not available: " + clazz,
117
            "strong crypto key pair generator not available: " + clazz, x);
139
            x);
140
      }
118
      }
141
  }
119
  }
142
143
  // Instance methods
144
  // -------------------------------------------------------------------------
145
}
120
}
(-)dss/DSSKey.java (-57 / +38 lines)
Lines 49-111 Link Here
49
import java.security.spec.DSAParameterSpec;
49
import java.security.spec.DSAParameterSpec;
50
50
51
/**
51
/**
52
 * <p>A base asbtract class for both public and private DSS (Digital Signature
52
 * A base asbtract class for both public and private DSS (Digital Signature
53
 * Standard) keys. It encapsulates the three DSS numbers: <code>p</code>,
53
 * Standard) keys. It encapsulates the three DSS numbers: <code>p</code>,
54
 * <code>q</code> and <code>g</code>.</p>
54
 * <code>q</code> and <code>g</code>.
55
 *
55
 * <p>
56
 * <p>According to the JDK, cryptographic <i>Keys</i> all have a <i>format</i>.
56
 * According to the JDK, cryptographic <i>Keys</i> all have a <i>format</i>.
57
 * The format used in this implementation is called <i>Raw</i>, and basically
57
 * The format used in this implementation is called <i>Raw</i>, and basically
58
 * consists of the raw byte sequences of algorithm parameters. The exact order
58
 * consists of the raw byte sequences of algorithm parameters. The exact order
59
 * of the byte sequences and the implementation details are given in each of
59
 * of the byte sequences and the implementation details are given in each of the
60
 * the relevant <code>getEncoded()</code> methods of each of the private and
60
 * relevant <code>getEncoded()</code> methods of each of the private and
61
 * public keys.</p>
61
 * public keys.
62
 *
62
 * 
63
 * @see DSSPrivateKey#getEncoded
63
 * @see DSSPrivateKey#getEncoded
64
 * @see DSSPublicKey#getEncoded
64
 * @see DSSPublicKey#getEncoded
65
 */
65
 */
66
public abstract class DSSKey implements Key, DSAKey
66
public abstract class DSSKey
67
    implements Key, DSAKey
67
{
68
{
68
  // Constants and variables
69
  // -------------------------------------------------------------------------
70
71
  /**
69
  /**
72
   * A prime modulus, where <code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code>
70
   * A prime modulus, where
73
   * for <code>512 &lt;= L &lt;= 1024</code> and <code>L</code> a multiple of
71
   * <code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code> for
72
   * <code>512 &lt;= L &lt;= 1024</code> and <code>L</code> a multiple of
74
   * <code>64</code>.
73
   * <code>64</code>.
75
   */
74
   */
76
  protected final BigInteger p;
75
  protected final BigInteger p;
77
76
78
  /**
77
  /**
79
   * A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup> &lt; q
78
   * A prime divisor of <code>p - 1</code>, where
79
   * <code>2<sup>159</sup> &lt; q
80
   * &lt; 2<sup>160</sup></code>.
80
   * &lt; 2<sup>160</sup></code>.
81
   */
81
   */
82
  protected final BigInteger q;
82
  protected final BigInteger q;
83
83
84
  /**
84
  /**
85
   * <code>g = h<sup>(p-1)</sup>/q mod p</code>, where <code>h</code> is any
85
   * <code>g = h<sup>(p-1)</sup>/q mod p</code>, where <code>h</code> is
86
   * integer with <code>1 &lt; h &lt; p - 1</code> such that <code>h<sup>
86
   * any integer with <code>1 &lt; h &lt; p - 1</code> such that <code>h<sup>
87
   * (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order <code>q mod p
87
   * (p-1)</sup>/q mod p > 1</code> (<code>g</code>
88
   * has order <code>q mod p
88
   * </code>).
89
   * </code>).
89
   */
90
   */
90
  protected final BigInteger g;
91
  protected final BigInteger g;
91
92
92
  /**
93
  /**
93
   * Identifier of the default encoding format to use when externalizing the
94
   * Identifier of the default encoding format to use when externalizing the key
94
   * key material.
95
   * material.
95
   */
96
   */
96
  protected final int defaultFormat;
97
  protected final int defaultFormat;
97
98
98
  /** String representation of this key. Cached for speed. */
99
  /** String representation of this key. Cached for speed. */
99
  private transient String str;
100
  private transient String str;
100
101
101
  // Constructor(s)
102
  // -------------------------------------------------------------------------
103
104
  /**
102
  /**
105
   * Trivial protected constructor.
103
   * Trivial protected constructor.
106
   * 
104
   * 
107
   * @param defaultFormat the identifier of the encoding format to use by
105
   * @param defaultFormat the identifier of the encoding format to use by
108
   * default when externalizing the key.
106
   *          default when externalizing the key.
109
   * @param p the DSS parameter <code>p</code>.
107
   * @param p the DSS parameter <code>p</code>.
110
   * @param q the DSS parameter <code>q</code>.
108
   * @param q the DSS parameter <code>q</code>.
111
   * @param g the DSS parameter <code>g</code>.
109
   * @param g the DSS parameter <code>g</code>.
Lines 121-141 Link Here
121
    this.g = g;
119
    this.g = g;
122
  }
120
  }
123
121
124
  // Class methods
125
  // -------------------------------------------------------------------------
126
127
  // Instance methods
128
  // -------------------------------------------------------------------------
129
130
  // java.security.interfaces.DSAKey interface implementation ----------------
131
132
  public DSAParams getParams()
122
  public DSAParams getParams()
133
  {
123
  {
134
    return new DSAParameterSpec(p, q, g);
124
    return new DSAParameterSpec(p, q, g);
135
  }
125
  }
136
126
137
  // java.security.Key interface implementation ------------------------------
138
139
  public String getAlgorithm()
127
  public String getAlgorithm()
140
  {
128
  {
141
    return Registry.DSS_KPG;
129
    return Registry.DSS_KPG;
Lines 152-178 Link Here
152
    return FormatUtil.getEncodingShortName(defaultFormat);
140
    return FormatUtil.getEncodingShortName(defaultFormat);
153
  }
141
  }
154
142
155
  // Other instance methods --------------------------------------------------
156
157
  /**
143
  /**
158
   * <p>Returns <code>true</code> if the designated object is an instance of
144
   * Returns <code>true</code> if the designated object is an instance of
159
   * {@link DSAKey} and has the same DSS (Digital Signature Standard) parameter
145
   * {@link DSAKey} and has the same DSS (Digital Signature Standard) parameter
160
   * values as this one.</p>
146
   * values as this one.
161
   *
147
   * 
162
   * @param obj the other non-null DSS key to compare to.
148
   * @param obj the other non-null DSS key to compare to.
163
   * @return <code>true</code> if the designated object is of the same type and
149
   * @return <code>true</code> if the designated object is of the same type
164
   * value as this one.
150
   *         and value as this one.
165
   */
151
   */
166
  public boolean equals(Object obj)
152
  public boolean equals(Object obj)
167
  {
153
  {
168
    if (obj == null)
154
    if (obj == null)
169
      {
155
      return false;
170
        return false;
156
171
      }
157
    if (! (obj instanceof DSAKey))
172
    if (!(obj instanceof DSAKey))
158
      return false;
173
      {
159
174
        return false;
175
      }
176
    DSAKey that = (DSAKey) obj;
160
    DSAKey that = (DSAKey) obj;
177
    return p.equals(that.getParams().getP())
161
    return p.equals(that.getParams().getP())
178
           && q.equals(that.getParams().getQ())
162
           && q.equals(that.getParams().getQ())
Lines 184-201 Link Here
184
    if (str == null)
168
    if (str == null)
185
      {
169
      {
186
        String ls = SystemProperties.getProperty("line.separator");
170
        String ls = SystemProperties.getProperty("line.separator");
187
        str = new StringBuilder().append(ls)
171
        str = new StringBuilder(ls)
188
        .append("defaultFormat=").append(defaultFormat).append(",").append(ls)
172
            .append("defaultFormat=").append(defaultFormat).append(",").append(ls)
189
        .append("p=0x").append(p.toString(16)).append(",").append(ls)
173
            .append("p=0x").append(p.toString(16)).append(",").append(ls)
190
        .append("q=0x").append(q.toString(16)).append(",").append(ls)
174
            .append("q=0x").append(q.toString(16)).append(",").append(ls)
191
        .append("g=0x").append(g.toString(16))
175
            .append("g=0x").append(g.toString(16))
192
        .toString();
176
            .toString();
193
      }
177
      }
194
195
    return str;
178
    return str;
196
  }
179
  }
197
180
198
  // abstract methods to be implemented by subclasses ------------------------
199
200
  public abstract byte[] getEncoded(int format);
181
  public abstract byte[] getEncoded(int format);
201
}
182
}
(-)dss/DSSKeyPairGenerator.java (-134 / +89 lines)
Lines 54-108 Link Here
54
import java.util.logging.Logger;
54
import java.util.logging.Logger;
55
55
56
/**
56
/**
57
 * <p>A key-pair generator for asymetric keys to use in conjunction with the DSS
57
 * A key-pair generator for asymetric keys to use in conjunction with the DSS
58
 * (Digital Signature Standard).</p>
58
 * (Digital Signature Standard).
59
 *
59
 * <p>
60
 * References:<br>
60
 * References:
61
 * <p>
61
 * <a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature
62
 * <a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature
62
 * Standard (DSS)</a>, Federal Information Processing Standards Publication 186.
63
 * Standard (DSS)</a>, Federal Information Processing Standards Publication
63
 * National Institute of Standards and Technology.
64
 * 186. National Institute of Standards and Technology.
64
 */
65
 */
65
public class DSSKeyPairGenerator implements IKeyPairGenerator
66
public class DSSKeyPairGenerator
67
    implements IKeyPairGenerator
66
{
68
{
67
  private static final Logger log = Logger.getLogger(DSSKeyPairGenerator.class.getName());
69
  private static final Logger log = Logger.getLogger(DSSKeyPairGenerator.class.getName());
70
68
  /** The BigInteger constant 2. */
71
  /** The BigInteger constant 2. */
69
  private static final BigInteger TWO = new BigInteger("2");
72
  private static final BigInteger TWO = BigInteger.valueOf(2L);
70
73
71
  /** Property name of the length (Integer) of the modulus (p) of a DSS key. */
74
  /** Property name of the length (Integer) of the modulus (p) of a DSS key. */
72
  public static final String MODULUS_LENGTH = "gnu.crypto.dss.L";
75
  public static final String MODULUS_LENGTH = "gnu.crypto.dss.L";
73
76
74
  /**
77
  /**
75
   * Property name of the Boolean indicating wether or not to use default pre-
78
   * Property name of the Boolean indicating wether or not to use default pre-
76
   * computed values of <code>p</code>, <code>q</code> and <code>g</code> for
79
   * computed values of <code>p</code>, <code>q</code> and <code>g</code>
77
   * a given modulus length. The ultimate behaviour of this generator with
80
   * for a given modulus length. The ultimate behaviour of this generator with
78
   * regard to using pre-computed parameter sets will depend on the value of
81
   * regard to using pre-computed parameter sets will depend on the value of
79
   * this property and of the following one {@link #STRICT_DEFAULTS}:
82
   * this property and of the following one {@link #STRICT_DEFAULTS}:
80
   * 
81
   * <ol>
83
   * <ol>
82
   *   <li>If this property is {@link Boolean#FALSE} then this generator
84
   * <li>If this property is {@link Boolean#FALSE} then this generator will
83
   *   will accept being setup for generating parameters for any modulus length
85
   * accept being setup for generating parameters for any modulus length
84
   *   provided the modulus length is between <code>512</code> and
86
   * provided the modulus length is between <code>512</code> and
85
   *   <code>1024</code>, and is of the form <code>512 + 64 * n</code>. In
87
   * <code>1024</code>, and is of the form <code>512 + 64 * n</code>. In
86
   *   addition, a new paramter set will always be generated; i.e. no pre-
88
   * addition, a new paramter set will always be generated; i.e. no pre-
87
   *   computed values are used.</li>
89
   * computed values are used.</li>
88
   *   
90
   * <li>If this property is {@link Boolean#TRUE} and the value of
89
   *   <li>If this property is {@link Boolean#TRUE} and the value of
91
   * {@link #STRICT_DEFAULTS} is also {@link Boolean#TRUE} then this generator
90
   *   {@link #STRICT_DEFAULTS} is also {@link Boolean#TRUE} then this generator
92
   * will only accept being setup for generating parameters for modulus lengths
91
   *   will only accept being setup for generating parameters for modulus
93
   * of <code>512</code>, <code>768</code> and <code>1024</code>. Any
92
   *   lengths of <code>512</code>, <code>768</code> and <code>1024</code>. Any
94
   * other value, of the modulus length, even if between <code>512</code> and
93
   *   other value, of the modulus length, even if between <code>512</code> and
95
   * <code>1024</code>, and of the form <code>512 + 64 * n</code>, will
94
   *   <code>1024</code>, and of the form <code>512 + 64 * n</code>, will cause
96
   * cause an {@link IllegalArgumentException} to be thrown. When those modulus
95
   *   an {@link IllegalArgumentException} to be thrown. When those modulus
97
   * length (<code>512</code>, <code>768</code>, and <code>1024</code>)
96
   *   length (<code>512</code>, <code>768</code>, and <code>1024</code>) are
98
   * are specified, the paramter set is always the same.</li>
97
   *   specified, the paramter set is always the same.</li>
99
   * <li>Finally, if this property is {@link Boolean#TRUE} and the value of
98
   *   
100
   * {@link #STRICT_DEFAULTS} is {@link Boolean#FALSE} then this generator will
99
   *   <li>Finally, if this property is {@link Boolean#TRUE} and the value of
101
   * behave as in point 1 above, except that it will use pre-computed values
100
   *   {@link #STRICT_DEFAULTS} is {@link Boolean#FALSE} then this generator
102
   * when possible; i.e. the modulus length is one of <code>512</code>,
101
   *   will behave as in point 1 above, except that it will use pre-computed
103
   * <code>768</code>, or <code>1024</code>.</li>
102
   *   values when possible; i.e. the modulus length is one of <code>512</code>,
103
   *   <code>768</code>, or <code>1024</code>.</li>
104
   * </ol>
104
   * </ol>
105
   * 
106
   * The default value of this property is {@link Boolean#TRUE}.
105
   * The default value of this property is {@link Boolean#TRUE}.
107
   */
106
   */
108
  public static final String USE_DEFAULTS = "gnu.crypto.dss.use.defaults";
107
  public static final String USE_DEFAULTS = "gnu.crypto.dss.use.defaults";
Lines 127-134 Link Here
127
126
128
  /**
127
  /**
129
   * Property name of an optional {@link DSAParameterSpec} instance to use for
128
   * Property name of an optional {@link DSAParameterSpec} instance to use for
130
   * this generator's <code>p</code>, <code>q</code>, and <code>g</code> values.
129
   * this generator's <code>p</code>, <code>q</code>, and <code>g</code>
131
   * The default is to generate these values or use pre-computed ones,
130
   * values. The default is to generate these values or use pre-computed ones,
132
   * depending on the value of the <code>USE_DEFAULTS</code> attribute.
131
   * depending on the value of the <code>USE_DEFAULTS</code> attribute.
133
   */
132
   */
134
  public static final String DSS_PARAMETERS = "gnu.crypto.dss.params";
133
  public static final String DSS_PARAMETERS = "gnu.crypto.dss.params";
Lines 147-201 Link Here
147
  private static final int DEFAULT_ENCODING_FORMAT = Registry.RAW_ENCODING_ID;
146
  private static final int DEFAULT_ENCODING_FORMAT = Registry.RAW_ENCODING_ID;
148
147
149
  /** Initial SHS context. */
148
  /** Initial SHS context. */
150
  private static final int[] T_SHS = new int[] { 0x67452301, 0xEFCDAB89,
149
  private static final int[] T_SHS = new int[] {
151
                                                0x98BADCFE, 0x10325476,
150
      0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
152
                                                0xC3D2E1F0 };
151
  };
153
152
154
  // from jdk1.3.1/docs/guide/security/CryptoSpec.html#AppB
153
  // from jdk1.3.1/docs/guide/security/CryptoSpec.html#AppB
155
  public static final DSAParameterSpec KEY_PARAMS_512 = new DSAParameterSpec(
154
  public static final DSAParameterSpec KEY_PARAMS_512 = new DSAParameterSpec(
156
                                                                             new BigInteger(
155
      new BigInteger(
157
                                                                                            "fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae"
156
          "fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae"
158
                                                                                                + "01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17",
157
        + "01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16),
159
                                                                                            16),
158
      new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16),
160
                                                                             new BigInteger(
159
      new BigInteger(
161
                                                                                            "962eddcc369cba8ebb260ee6b6a126d9346e38c5",
160
          "678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e"
162
                                                                                            16),
161
        + "35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16));
163
                                                                             new BigInteger(
164
                                                                                            "678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e"
165
                                                                                                + "35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4",
166
                                                                                            16));
167
168
  public static final DSAParameterSpec KEY_PARAMS_768 = new DSAParameterSpec(
162
  public static final DSAParameterSpec KEY_PARAMS_768 = new DSAParameterSpec(
169
                                                                             new BigInteger(
163
      new BigInteger(
170
                                                                                            "e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d8901419"
164
          "e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d8901419"
171
                                                                                                + "22d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d77"
165
        + "22d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d77"
172
                                                                                                + "7d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf",
166
        + "7d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", 16),
173
                                                                                            16),
167
      new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16),
174
                                                                             new BigInteger(
168
      new BigInteger(
175
                                                                                            "9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511",
169
          "30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4"
176
                                                                                            16),
170
        + "dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d8"
177
                                                                             new BigInteger(
171
        + "3c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", 16));
178
                                                                                            "30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4"
179
                                                                                                + "dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d8"
180
                                                                                                + "3c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252",
181
                                                                                            16));
182
183
  public static final DSAParameterSpec KEY_PARAMS_1024 = new DSAParameterSpec(
172
  public static final DSAParameterSpec KEY_PARAMS_1024 = new DSAParameterSpec(
184
                                                                              new BigInteger(
173
      new BigInteger(
185
                                                                                             "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669"
174
          "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669"
186
                                                                                                 + "455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b7"
175
        + "455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b7"
187
                                                                                                 + "6b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb"
176
        + "6b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb"
188
                                                                                                 + "83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7",
177
        + "83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16),
189
                                                                                             16),
178
      new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16),
190
                                                                              new BigInteger(
179
      new BigInteger(
191
                                                                                             "9760508f15230bccb292b982a2eb840bf0581cf5",
180
          "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d078267"
192
                                                                                             16),
181
        + "5159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e1"
193
                                                                              new BigInteger(
182
        + "3c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243b"
194
                                                                                             "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d078267"
183
        + "cca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16));
195
                                                                                                 + "5159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e1"
196
                                                                                                 + "3c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243b"
197
                                                                                                 + "cca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a",
198
                                                                                             16));
199
184
200
  private static final BigInteger TWO_POW_160 = TWO.pow(160);
185
  private static final BigInteger TWO_POW_160 = TWO.pow(160);
201
186
Lines 225-255 Link Here
225
  /** Preferred encoding format of generated keys. */
210
  /** Preferred encoding format of generated keys. */
226
  private int preferredFormat;
211
  private int preferredFormat;
227
212
228
  // Constructor(s)
229
  // -------------------------------------------------------------------------
230
231
  // implicit 0-arguments constructor
232
233
  // Class methods
234
  // -------------------------------------------------------------------------
235
236
  // Instance methods
237
  // -------------------------------------------------------------------------
238
239
  // gnu.crypto.key.IKeyPairGenerator interface implementation ---------------
240
241
  public String name()
213
  public String name()
242
  {
214
  {
243
    return Registry.DSS_KPG;
215
    return Registry.DSS_KPG;
244
  }
216
  }
245
217
246
  /**
218
  /**
247
   * <p>Configures this instance.</p>
219
   * Configures this instance.
248
   *
220
   * 
249
   * @param attributes the map of name/value pairs to use.
221
   * @param attributes the map of name/value pairs to use.
250
   * @exception IllegalArgumentException if the designated MODULUS_LENGTH
222
   * @exception IllegalArgumentException if the designated MODULUS_LENGTH value
251
   * value is not greater than 512, less than 1024 and not of the form
223
   *              is not greater than 512, less than 1024 and not of the form
252
   * <code>512 + 64j</code>.
224
   *              <code>512 + 64j</code>.
253
   */
225
   */
254
  public void setup(Map attributes)
226
  public void setup(Map attributes)
255
  {
227
  {
Lines 262-270 Link Here
262
    // should we use the default pre-computed params?
234
    // should we use the default pre-computed params?
263
    Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS);
235
    Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS);
264
    if (useDefaults == null)
236
    if (useDefaults == null)
265
      {
237
      useDefaults = Boolean.TRUE;
266
        useDefaults = Boolean.TRUE;
267
      }
268
238
269
    Boolean strictDefaults = (Boolean) attributes.get(STRICT_DEFAULTS);
239
    Boolean strictDefaults = (Boolean) attributes.get(STRICT_DEFAULTS);
270
    if (strictDefaults == null)
240
    if (strictDefaults == null)
Lines 316-331 Link Here
316
        q = null;
286
        q = null;
317
        g = null;
287
        g = null;
318
      }
288
      }
319
320
    // do we have a SecureRandom, or should we use our own?
289
    // do we have a SecureRandom, or should we use our own?
321
    rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
290
    rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
322
323
    // what is the preferred encoding format
291
    // what is the preferred encoding format
324
    Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT);
292
    Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT);
325
    preferredFormat = formatID == null
293
    preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT
326
        ? DEFAULT_ENCODING_FORMAT
294
                                       : formatID.intValue();
327
        : formatID.intValue();
328
329
    // set the seed-key
295
    // set the seed-key
330
    byte[] kb = new byte[20]; // we need 160 bits of randomness
296
    byte[] kb = new byte[20]; // we need 160 bits of randomness
331
    nextRandomBytes(kb);
297
    nextRandomBytes(kb);
Lines 353-418 Link Here
353
            log.fine("g: " + g.toString(16));
319
            log.fine("g: " + g.toString(16));
354
          }
320
          }
355
      }
321
      }
356
357
    BigInteger x = nextX();
322
    BigInteger x = nextX();
358
    BigInteger y = g.modPow(x, p);
323
    BigInteger y = g.modPow(x, p);
359
360
    PublicKey pubK = new DSSPublicKey(preferredFormat, p, q, g, y);
324
    PublicKey pubK = new DSSPublicKey(preferredFormat, p, q, g, y);
361
    PrivateKey secK = new DSSPrivateKey(preferredFormat, p, q, g, x);
325
    PrivateKey secK = new DSSPrivateKey(preferredFormat, p, q, g, x);
362
363
    return new KeyPair(pubK, secK);
326
    return new KeyPair(pubK, secK);
364
  }
327
  }
365
328
366
  // Other instance methods --------------------------------------------------
367
368
  /**
329
  /**
369
   * <p>This method applies the following algorithm described in 3.1 of
330
   * This method applies the following algorithm described in 3.1 of FIPS-186:
370
   * FIPS-186:</p>
371
   *
372
   * <ol>
331
   * <ol>
373
   *    <li>XSEED = optional user input.</li>
332
   * <li>XSEED = optional user input.</li>
374
   *    <li>XVAL = (XKEY + XSEED) mod 2<sup>b</sup>.</li>
333
   * <li>XVAL = (XKEY + XSEED) mod 2<sup>b</sup>.</li>
375
   *    <li>x = G(t, XVAL) mod q.</li>
334
   * <li>x = G(t, XVAL) mod q.</li>
376
   *    <li>XKEY = (1 + XKEY + x) mod 2<sup>b</sup>.</li>
335
   * <li>XKEY = (1 + XKEY + x) mod 2<sup>b</sup>.</li>
377
   * </ol>
336
   * </ol>
378
   *
337
   * <p>
379
   * <p>Where <code>b</code> is the length of a secret b-bit seed-key (XKEY).</p>
338
   * Where <code>b</code> is the length of a secret b-bit seed-key (XKEY).
380
   *
339
   * <p>
381
   * <p>Note that in this implementation, XSEED, the optional user input, is
340
   * Note that in this implementation, XSEED, the optional user input, is always
382
   * always zero.</p>
341
   * zero.
383
   */
342
   */
384
  private synchronized BigInteger nextX()
343
  private synchronized BigInteger nextX()
385
  {
344
  {
386
    byte[] xk = XKEY.toByteArray();
345
    byte[] xk = XKEY.toByteArray();
387
    byte[] in = new byte[64]; // 512-bit block for SHS
346
    byte[] in = new byte[64]; // 512-bit block for SHS
388
    System.arraycopy(xk, 0, in, 0, xk.length);
347
    System.arraycopy(xk, 0, in, 0, xk.length);
389
390
    int[] H = Sha160.G(T_SHS[0], T_SHS[1], T_SHS[2], T_SHS[3], T_SHS[4], in, 0);
348
    int[] H = Sha160.G(T_SHS[0], T_SHS[1], T_SHS[2], T_SHS[3], T_SHS[4], in, 0);
391
    byte[] h = new byte[20];
349
    byte[] h = new byte[20];
392
    for (int i = 0, j = 0; i < 5; i++)
350
    for (int i = 0, j = 0; i < 5; i++)
393
      {
351
      {
394
        h[j++] = (byte) (H[i] >>> 24);
352
        h[j++] = (byte)(H[i] >>> 24);
395
        h[j++] = (byte) (H[i] >>> 16);
353
        h[j++] = (byte)(H[i] >>> 16);
396
        h[j++] = (byte) (H[i] >>> 8);
354
        h[j++] = (byte)(H[i] >>> 8);
397
        h[j++] = (byte) H[i];
355
        h[j++] = (byte) H[i];
398
      }
356
      }
399
    BigInteger result = new BigInteger(1, h).mod(q);
357
    BigInteger result = new BigInteger(1, h).mod(q);
400
    XKEY = XKEY.add(result).add(BigInteger.ONE).mod(TWO_POW_160);
358
    XKEY = XKEY.add(result).add(BigInteger.ONE).mod(TWO_POW_160);
401
402
    return result;
359
    return result;
403
  }
360
  }
404
361
405
  /**
362
  /**
406
   * <p>Fills the designated byte array with random data.</p>
363
   * Fills the designated byte array with random data.
407
   *
364
   * 
408
   * @param buffer the byte array to fill with random data.
365
   * @param buffer the byte array to fill with random data.
409
   */
366
   */
410
  private void nextRandomBytes(byte[] buffer)
367
  private void nextRandomBytes(byte[] buffer)
411
  {
368
  {
412
    if (rnd != null)
369
    if (rnd != null)
413
      {
370
      rnd.nextBytes(buffer);
414
        rnd.nextBytes(buffer);
415
      }
416
    else
371
    else
417
      getDefaultPRNG().nextBytes(buffer);
372
      getDefaultPRNG().nextBytes(buffer);
418
  }
373
  }
(-)dss/DSSKeyPairPKCS8Codec.java (-4 / +2 lines)
Lines 159-169 Link Here
159
      }
159
      }
160
    catch (IOException e)
160
    catch (IOException e)
161
      {
161
      {
162
        InvalidParameterException y = new InvalidParameterException();
162
        InvalidParameterException y = new InvalidParameterException(e.getMessage());
163
        y.initCause(e);
163
        y.initCause(e);
164
        throw y;
164
        throw y;
165
      }
165
      }
166
167
    return result;
166
    return result;
168
  }
167
  }
169
168
Lines 187-193 Link Here
187
  {
186
  {
188
    if (Configuration.DEBUG)
187
    if (Configuration.DEBUG)
189
      log.entering(this.getClass().getName(), "decodePrivateKey");
188
      log.entering(this.getClass().getName(), "decodePrivateKey");
190
191
    if (input == null)
189
    if (input == null)
192
      throw new InvalidParameterException("Input bytes MUST NOT be null");
190
      throw new InvalidParameterException("Input bytes MUST NOT be null");
193
191
Lines 240-246 Link Here
240
      }
238
      }
241
    catch (IOException e)
239
    catch (IOException e)
242
      {
240
      {
243
        InvalidParameterException y = new InvalidParameterException();
241
        InvalidParameterException y = new InvalidParameterException(e.getMessage());
244
        y.initCause(e);
242
        y.initCause(e);
245
        throw y;
243
        throw y;
246
      }
244
      }
(-)dss/DSSKeyPairRawCodec.java (-142 / +108 lines)
Lines 47-137 Link Here
47
import java.security.PublicKey;
47
import java.security.PublicKey;
48
48
49
/**
49
/**
50
 * <p>An object that implements the {@link IKeyPairCodec} operations for the
50
 * An object that implements the {@link IKeyPairCodec} operations for the
51
 * <i>Raw</i> format to use with DSS keypairs.</p>
51
 * <i>Raw</i> format to use with DSS keypairs.
52
 */
52
 */
53
public class DSSKeyPairRawCodec implements IKeyPairCodec
53
public class DSSKeyPairRawCodec
54
    implements IKeyPairCodec
54
{
55
{
55
56
  // Constants and variables
57
  // -------------------------------------------------------------------------
58
59
  // Constructor(s)
60
  // -------------------------------------------------------------------------
61
62
  // implicit 0-arguments constructor
56
  // implicit 0-arguments constructor
63
57
64
  // Class methods
65
  // -------------------------------------------------------------------------
66
67
  // Instance methods
68
  // -------------------------------------------------------------------------
69
70
  // gnu.crypto.keys.IKeyPairCodec interface implementation ------------------
71
72
  public int getFormatID()
58
  public int getFormatID()
73
  {
59
  {
74
    return RAW_FORMAT;
60
    return RAW_FORMAT;
75
  }
61
  }
76
62
77
  /**
63
  /**
78
   * <p>Returns the encoded form of the designated DSS (Digital Signature
64
   * Returns the encoded form of the designated DSS (Digital Signature Standard)
79
   * Standard) public key according to the <i>Raw</i> format supported by
65
   * public key according to the <i>Raw</i> format supported by this library.
80
   * this library.</p>
66
   * <p>
81
   *
67
   * The <i>Raw</i> format for a DSA public key, in this implementation, is a
82
   * <p>The <i>Raw</i> format for a DSA public key, in this implementation, is
68
   * byte sequence consisting of the following:
83
   * a byte sequence consisting of the following:</p>
84
   * <ol>
69
   * <ol>
85
   *    <li>4-byte magic consisting of the value of the literal
70
   * <li>4-byte magic consisting of the value of the literal
86
   *    {@link Registry#MAGIC_RAW_DSS_PUBLIC_KEY},<li>
71
   * {@link Registry#MAGIC_RAW_DSS_PUBLIC_KEY},
87
   *    <li>1-byte version consisting of the constant: 0x01,</li>
72
   * <li>
88
   *    <li>4-byte count of following bytes representing the DSA parameter
73
   * <li>1-byte version consisting of the constant: 0x01,</li>
89
   *    <code>p</code> in internet order,</li>
74
   * <li>4-byte count of following bytes representing the DSA parameter
90
   *    <li>n-bytes representation of a {@link BigInteger} obtained by invoking
75
   * <code>p</code> in internet order,</li>
91
   *    the <code>toByteArray()</code> method on the DSA parameter
76
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
92
   *    <code>p</code>,</li>
77
   * the <code>toByteArray()</code> method on the DSA parameter <code>p</code>,
93
   *    <li>4-byte count of following bytes representing the DSA parameter
78
   * </li>
94
   *    <code>q</code>,</li>
79
   * <li>4-byte count of following bytes representing the DSA parameter
95
   *    <li>n-bytes representation of a {@link BigInteger} obtained by invoking
80
   * <code>q</code>,</li>
96
   *    the <code>toByteArray()</code> method on the DSA parameter
81
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
97
   *    <code>q</code>,</li>
82
   * the <code>toByteArray()</code> method on the DSA parameter <code>q</code>,
98
   *    <li>4-byte count of following bytes representing the DSA parameter
83
   * </li>
99
   *    <code>g</code>,</li>
84
   * <li>4-byte count of following bytes representing the DSA parameter
100
   *    <li>n-bytes representation of a {@link BigInteger} obtained by invoking
85
   * <code>g</code>,</li>
101
   *    the <code>toByteArray()</code> method on the DSA parameter
86
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
102
   *    <code>g</code>,</li>
87
   * the <code>toByteArray()</code> method on the DSA parameter <code>g</code>,
103
   *    <li>4-byte count of following bytes representing the DSA parameter
88
   * </li>
104
   *    <code>y</code>,</li>
89
   * <li>4-byte count of following bytes representing the DSA parameter
105
   *    <li>n-bytes representation of a {@link BigInteger} obtained by invoking
90
   * <code>y</code>,</li>
106
   *    the <code>toByteArray()</code> method on the DSA parameter
91
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
107
   *    <code>y</code>,</li>
92
   * the <code>toByteArray()</code> method on the DSA parameter <code>y</code>,
93
   * </li>
108
   * </ol>
94
   * </ol>
109
   *
95
   * 
110
   * @param key the key to encode.
96
   * @param key the key to encode.
111
   * @return the <i>Raw</i> format encoding of the designated key.
97
   * @return the <i>Raw</i> format encoding of the designated key.
112
   * @throws IllegalArgumentException if the designated key is not a DSS
98
   * @throws IllegalArgumentException if the designated key is not a DSS
113
   * (Digital Signature Standard) one.
99
   *           (Digital Signature Standard) one.
114
   * @see Registry#MAGIC_RAW_DSS_PUBLIC_KEY
100
   * @see Registry#MAGIC_RAW_DSS_PUBLIC_KEY
115
   */
101
   */
116
  public byte[] encodePublicKey(PublicKey key)
102
  public byte[] encodePublicKey(PublicKey key)
117
  {
103
  {
118
    if (!(key instanceof DSSPublicKey))
104
    if (! (key instanceof DSSPublicKey))
119
      {
105
      throw new IllegalArgumentException("key");
120
        throw new IllegalArgumentException("key");
121
      }
122
106
123
    DSSPublicKey dssKey = (DSSPublicKey) key;
107
    DSSPublicKey dssKey = (DSSPublicKey) key;
124
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
108
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
125
126
    // magic
109
    // magic
127
    baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0]);
110
    baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0]);
128
    baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1]);
111
    baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1]);
129
    baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2]);
112
    baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2]);
130
    baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3]);
113
    baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3]);
131
132
    // version
114
    // version
133
    baos.write(0x01);
115
    baos.write(0x01);
134
135
    // p
116
    // p
136
    byte[] buffer = dssKey.getParams().getP().toByteArray();
117
    byte[] buffer = dssKey.getParams().getP().toByteArray();
137
    int length = buffer.length;
118
    int length = buffer.length;
Lines 140-146 Link Here
140
    baos.write((length >>> 8) & 0xFF);
121
    baos.write((length >>> 8) & 0xFF);
141
    baos.write(length & 0xFF);
122
    baos.write(length & 0xFF);
142
    baos.write(buffer, 0, length);
123
    baos.write(buffer, 0, length);
143
144
    // q
124
    // q
145
    buffer = dssKey.getParams().getQ().toByteArray();
125
    buffer = dssKey.getParams().getQ().toByteArray();
146
    length = buffer.length;
126
    length = buffer.length;
Lines 149-155 Link Here
149
    baos.write((length >>> 8) & 0xFF);
129
    baos.write((length >>> 8) & 0xFF);
150
    baos.write(length & 0xFF);
130
    baos.write(length & 0xFF);
151
    baos.write(buffer, 0, length);
131
    baos.write(buffer, 0, length);
152
153
    // g
132
    // g
154
    buffer = dssKey.getParams().getG().toByteArray();
133
    buffer = dssKey.getParams().getG().toByteArray();
155
    length = buffer.length;
134
    length = buffer.length;
Lines 158-164 Link Here
158
    baos.write((length >>> 8) & 0xFF);
137
    baos.write((length >>> 8) & 0xFF);
159
    baos.write(length & 0xFF);
138
    baos.write(length & 0xFF);
160
    baos.write(buffer, 0, length);
139
    baos.write(buffer, 0, length);
161
162
    // y
140
    // y
163
    buffer = dssKey.getY().toByteArray();
141
    buffer = dssKey.getY().toByteArray();
164
    length = buffer.length;
142
    length = buffer.length;
Lines 167-173 Link Here
167
    baos.write((length >>> 8) & 0xFF);
145
    baos.write((length >>> 8) & 0xFF);
168
    baos.write(length & 0xFF);
146
    baos.write(length & 0xFF);
169
    baos.write(buffer, 0, length);
147
    baos.write(buffer, 0, length);
170
171
    return baos.toByteArray();
148
    return baos.toByteArray();
172
  }
149
  }
173
150
Lines 178-289 Link Here
178
        || k[1] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1]
155
        || k[1] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1]
179
        || k[2] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2]
156
        || k[2] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2]
180
        || k[3] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3])
157
        || k[3] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3])
181
      {
158
      throw new IllegalArgumentException("magic");
182
        throw new IllegalArgumentException("magic");
183
      }
184
159
185
    // version
160
    // version
186
    if (k[4] != 0x01)
161
    if (k[4] != 0x01)
187
      {
162
      throw new IllegalArgumentException("version");
188
        throw new IllegalArgumentException("version");
189
      }
190
    int i = 5;
191
163
164
    int i = 5;
192
    int l;
165
    int l;
193
    byte[] buffer;
166
    byte[] buffer;
194
195
    // p
167
    // p
196
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
168
    l =  k[i++]         << 24
197
        | (k[i++] & 0xFF);
169
      | (k[i++] & 0xFF) << 16
170
      | (k[i++] & 0xFF) << 8
171
      | (k[i++] & 0xFF);
198
    buffer = new byte[l];
172
    buffer = new byte[l];
199
    System.arraycopy(k, i, buffer, 0, l);
173
    System.arraycopy(k, i, buffer, 0, l);
200
    i += l;
174
    i += l;
201
    BigInteger p = new BigInteger(1, buffer);
175
    BigInteger p = new BigInteger(1, buffer);
202
203
    // q
176
    // q
204
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
177
    l =  k[i++]         << 24
205
        | (k[i++] & 0xFF);
178
      | (k[i++] & 0xFF) << 16
179
      | (k[i++] & 0xFF) << 8
180
      | (k[i++] & 0xFF);
206
    buffer = new byte[l];
181
    buffer = new byte[l];
207
    System.arraycopy(k, i, buffer, 0, l);
182
    System.arraycopy(k, i, buffer, 0, l);
208
    i += l;
183
    i += l;
209
    BigInteger q = new BigInteger(1, buffer);
184
    BigInteger q = new BigInteger(1, buffer);
210
211
    // g
185
    // g
212
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
186
    l =  k[i++]         << 24
213
        | (k[i++] & 0xFF);
187
      | (k[i++] & 0xFF) << 16
188
      | (k[i++] & 0xFF) << 8
189
      | (k[i++] & 0xFF);
214
    buffer = new byte[l];
190
    buffer = new byte[l];
215
    System.arraycopy(k, i, buffer, 0, l);
191
    System.arraycopy(k, i, buffer, 0, l);
216
    i += l;
192
    i += l;
217
    BigInteger g = new BigInteger(1, buffer);
193
    BigInteger g = new BigInteger(1, buffer);
218
219
    // y
194
    // y
220
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
195
    l =  k[i++]         << 24
221
        | (k[i++] & 0xFF);
196
      | (k[i++] & 0xFF) << 16
197
      | (k[i++] & 0xFF) << 8
198
      | (k[i++] & 0xFF);
222
    buffer = new byte[l];
199
    buffer = new byte[l];
223
    System.arraycopy(k, i, buffer, 0, l);
200
    System.arraycopy(k, i, buffer, 0, l);
224
    i += l;
201
    i += l;
225
    BigInteger y = new BigInteger(1, buffer);
202
    BigInteger y = new BigInteger(1, buffer);
226
227
    return new DSSPublicKey(p, q, g, y);
203
    return new DSSPublicKey(p, q, g, y);
228
  }
204
  }
229
205
230
  /**
206
  /**
231
   * <p>Returns the encoded form of the designated DSS (Digital Signature
207
   * Returns the encoded form of the designated DSS (Digital Signature Standard)
232
   * Standard) private key according to the <i>Raw</i> format supported by
208
   * private key according to the <i>Raw</i> format supported by this library.
233
   * this library.</p>
209
   * <p>
234
   *
210
   * The <i>Raw</i> format for a DSA private key, in this implementation, is a
235
   * <p>The <i>Raw</i> format for a DSA private key, in this implementation, is
211
   * byte sequence consisting of the following:
236
   * a byte sequence consisting of the following:</p>
237
   * <ol>
212
   * <ol>
238
   *    <li>4-byte magic consisting of the value of the literal
213
   * <li>4-byte magic consisting of the value of the literal
239
   *    {@link Registry#MAGIC_RAW_DSS_PRIVATE_KEY},<li>
214
   * {@link Registry#MAGIC_RAW_DSS_PRIVATE_KEY},
240
   *    <li>1-byte version consisting of the constant: 0x01,</li>
215
   * <li>
241
   *    <li>4-byte count of following bytes representing the DSA parameter
216
   * <li>1-byte version consisting of the constant: 0x01,</li>
242
   *    <code>p</code> in internet order,</li>
217
   * <li>4-byte count of following bytes representing the DSA parameter
243
   *    <li>n-bytes representation of a {@link BigInteger} obtained by invoking
218
   * <code>p</code> in internet order,</li>
244
   *    the <code>toByteArray()</code> method on the DSA parameter
219
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
245
   *    <code>p</code>,</li>
220
   * the <code>toByteArray()</code> method on the DSA parameter <code>p</code>,
246
   *    <li>4-byte count of following bytes representing the DSA parameter
221
   * </li>
247
   *    <code>q</code>,</li>
222
   * <li>4-byte count of following bytes representing the DSA parameter
248
   *    <li>n-bytes representation of a {@link BigInteger} obtained by invoking
223
   * <code>q</code>,</li>
249
   *    the <code>toByteArray()</code> method on the DSA parameter
224
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
250
   *    <code>q</code>,</li>
225
   * the <code>toByteArray()</code> method on the DSA parameter <code>q</code>,
251
   *    <li>4-byte count of following bytes representing the DSA parameter
226
   * </li>
252
   *    <code>g</code>,</li>
227
   * <li>4-byte count of following bytes representing the DSA parameter
253
   *    <li>n-bytes representation of a {@link BigInteger} obtained by invoking
228
   * <code>g</code>,</li>
254
   *    the <code>toByteArray()</code> method on the DSA parameter
229
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
255
   *    <code>g</code>,</li>
230
   * the <code>toByteArray()</code> method on the DSA parameter <code>g</code>,
256
   *    <li>4-byte count of following bytes representing the DSA parameter
231
   * </li>
257
   *    <code>x</code>,</li>
232
   * <li>4-byte count of following bytes representing the DSA parameter
258
   *    <li>n-bytes representation of a {@link BigInteger} obtained by invoking
233
   * <code>x</code>,</li>
259
   *    the <code>toByteArray()</code> method on the DSA parameter
234
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
260
   *    <code>x</code>,</li>
235
   * the <code>toByteArray()</code> method on the DSA parameter <code>x</code>,
236
   * </li>
261
   * </ol>
237
   * </ol>
262
   *
238
   * 
263
   * @param key the key to encode.
239
   * @param key the key to encode.
264
   * @return the <i>Raw</i> format encoding of the designated key.
240
   * @return the <i>Raw</i> format encoding of the designated key.
265
   * @throws IllegalArgumentException if the designated key is not a DSS
241
   * @throws IllegalArgumentException if the designated key is not a DSS
266
   * (Digital Signature Standard) one.
242
   *           (Digital Signature Standard) one.
267
   */
243
   */
268
  public byte[] encodePrivateKey(PrivateKey key)
244
  public byte[] encodePrivateKey(PrivateKey key)
269
  {
245
  {
270
    if (!(key instanceof DSSPrivateKey))
246
    if (! (key instanceof DSSPrivateKey))
271
      {
247
      throw new IllegalArgumentException("key");
272
        throw new IllegalArgumentException("key");
273
      }
274
248
275
    DSSPrivateKey dssKey = (DSSPrivateKey) key;
249
    DSSPrivateKey dssKey = (DSSPrivateKey) key;
276
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
250
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
277
278
    // magic
251
    // magic
279
    baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0]);
252
    baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0]);
280
    baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1]);
253
    baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1]);
281
    baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2]);
254
    baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2]);
282
    baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3]);
255
    baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3]);
283
284
    // version
256
    // version
285
    baos.write(0x01);
257
    baos.write(0x01);
286
287
    // p
258
    // p
288
    byte[] buffer = dssKey.getParams().getP().toByteArray();
259
    byte[] buffer = dssKey.getParams().getP().toByteArray();
289
    int length = buffer.length;
260
    int length = buffer.length;
Lines 292-298 Link Here
292
    baos.write((length >>> 8) & 0xFF);
263
    baos.write((length >>> 8) & 0xFF);
293
    baos.write(length & 0xFF);
264
    baos.write(length & 0xFF);
294
    baos.write(buffer, 0, length);
265
    baos.write(buffer, 0, length);
295
296
    // q
266
    // q
297
    buffer = dssKey.getParams().getQ().toByteArray();
267
    buffer = dssKey.getParams().getQ().toByteArray();
298
    length = buffer.length;
268
    length = buffer.length;
Lines 301-307 Link Here
301
    baos.write((length >>> 8) & 0xFF);
271
    baos.write((length >>> 8) & 0xFF);
302
    baos.write(length & 0xFF);
272
    baos.write(length & 0xFF);
303
    baos.write(buffer, 0, length);
273
    baos.write(buffer, 0, length);
304
305
    // g
274
    // g
306
    buffer = dssKey.getParams().getG().toByteArray();
275
    buffer = dssKey.getParams().getG().toByteArray();
307
    length = buffer.length;
276
    length = buffer.length;
Lines 310-316 Link Here
310
    baos.write((length >>> 8) & 0xFF);
279
    baos.write((length >>> 8) & 0xFF);
311
    baos.write(length & 0xFF);
280
    baos.write(length & 0xFF);
312
    baos.write(buffer, 0, length);
281
    baos.write(buffer, 0, length);
313
314
    // x
282
    // x
315
    buffer = dssKey.getX().toByteArray();
283
    buffer = dssKey.getX().toByteArray();
316
    length = buffer.length;
284
    length = buffer.length;
Lines 319-325 Link Here
319
    baos.write((length >>> 8) & 0xFF);
287
    baos.write((length >>> 8) & 0xFF);
320
    baos.write(length & 0xFF);
288
    baos.write(length & 0xFF);
321
    baos.write(buffer, 0, length);
289
    baos.write(buffer, 0, length);
322
323
    return baos.toByteArray();
290
    return baos.toByteArray();
324
  }
291
  }
325
292
Lines 330-381 Link Here
330
        || k[1] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1]
297
        || k[1] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1]
331
        || k[2] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2]
298
        || k[2] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2]
332
        || k[3] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3])
299
        || k[3] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3])
333
      {
300
      throw new IllegalArgumentException("magic");
334
        throw new IllegalArgumentException("magic");
335
      }
336
301
337
    // version
302
    // version
338
    if (k[4] != 0x01)
303
    if (k[4] != 0x01)
339
      {
304
      throw new IllegalArgumentException("version");
340
        throw new IllegalArgumentException("version");
341
      }
342
    int i = 5;
343
305
306
    int i = 5;
344
    int l;
307
    int l;
345
    byte[] buffer;
308
    byte[] buffer;
346
347
    // p
309
    // p
348
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
310
    l =  k[i++]         << 24
349
        | (k[i++] & 0xFF);
311
      | (k[i++] & 0xFF) << 16
312
      | (k[i++] & 0xFF) << 8
313
      | (k[i++] & 0xFF);
350
    buffer = new byte[l];
314
    buffer = new byte[l];
351
    System.arraycopy(k, i, buffer, 0, l);
315
    System.arraycopy(k, i, buffer, 0, l);
352
    i += l;
316
    i += l;
353
    BigInteger p = new BigInteger(1, buffer);
317
    BigInteger p = new BigInteger(1, buffer);
354
355
    // q
318
    // q
356
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
319
    l =  k[i++]         << 24
357
        | (k[i++] & 0xFF);
320
      | (k[i++] & 0xFF) << 16
321
      | (k[i++] & 0xFF) << 8
322
      | (k[i++] & 0xFF);
358
    buffer = new byte[l];
323
    buffer = new byte[l];
359
    System.arraycopy(k, i, buffer, 0, l);
324
    System.arraycopy(k, i, buffer, 0, l);
360
    i += l;
325
    i += l;
361
    BigInteger q = new BigInteger(1, buffer);
326
    BigInteger q = new BigInteger(1, buffer);
362
363
    // g
327
    // g
364
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
328
    l =  k[i++]         << 24
365
        | (k[i++] & 0xFF);
329
      | (k[i++] & 0xFF) << 16
330
      | (k[i++] & 0xFF) << 8
331
      | (k[i++] & 0xFF);
366
    buffer = new byte[l];
332
    buffer = new byte[l];
367
    System.arraycopy(k, i, buffer, 0, l);
333
    System.arraycopy(k, i, buffer, 0, l);
368
    i += l;
334
    i += l;
369
    BigInteger g = new BigInteger(1, buffer);
335
    BigInteger g = new BigInteger(1, buffer);
370
371
    // x
336
    // x
372
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
337
    l =  k[i++]         << 24
373
        | (k[i++] & 0xFF);
338
      | (k[i++] & 0xFF) << 16
339
      | (k[i++] & 0xFF) << 8
340
      | (k[i++] & 0xFF);
374
    buffer = new byte[l];
341
    buffer = new byte[l];
375
    System.arraycopy(k, i, buffer, 0, l);
342
    System.arraycopy(k, i, buffer, 0, l);
376
    i += l;
343
    i += l;
377
    BigInteger x = new BigInteger(1, buffer);
344
    BigInteger x = new BigInteger(1, buffer);
378
379
    return new DSSPrivateKey(p, q, g, x);
345
    return new DSSPrivateKey(p, q, g, x);
380
  }
346
  }
381
}
347
}
(-)dss/DSSKeyPairX509Codec.java (-4 / +2 lines)
Lines 157-167 Link Here
157
      }
157
      }
158
    catch (IOException x)
158
    catch (IOException x)
159
      {
159
      {
160
        InvalidParameterException e = new InvalidParameterException();
160
        InvalidParameterException e = new InvalidParameterException(x.getMessage());
161
        e.initCause(x);
161
        e.initCause(x);
162
        throw e;
162
        throw e;
163
      }
163
      }
164
165
    return result;
164
    return result;
166
  }
165
  }
167
166
Lines 230-240 Link Here
230
      }
229
      }
231
    catch (IOException x)
230
    catch (IOException x)
232
      {
231
      {
233
        InvalidParameterException e = new InvalidParameterException();
232
        InvalidParameterException e = new InvalidParameterException(x.getMessage());
234
        e.initCause(x);
233
        e.initCause(x);
235
        throw e;
234
        throw e;
236
      }
235
      }
237
238
    return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
236
    return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
239
  }
237
  }
240
238
(-)dss/DSSPrivateKey.java (-41 / +26 lines)
Lines 48-71 Link Here
48
import java.security.interfaces.DSAPrivateKey;
48
import java.security.interfaces.DSAPrivateKey;
49
49
50
/**
50
/**
51
 * <p>An object that embodies a DSS (Digital Signature Standard) private key.</p>
51
 * An object that embodies a DSS (Digital Signature Standard) private key.
52
 *
52
 * 
53
 * @see #getEncoded
53
 * @see #getEncoded
54
 */
54
 */
55
public class DSSPrivateKey extends DSSKey implements PrivateKey, DSAPrivateKey
55
public class DSSPrivateKey
56
    extends DSSKey
57
    implements PrivateKey, DSAPrivateKey
56
{
58
{
57
  /**
59
  /**
58
   * <p>A randomly or pseudorandomly generated integer with <code>0 &lt; x &lt;
60
   * A randomly or pseudorandomly generated integer with <code>0 &lt; x &lt;
59
   * q</code>.</p>
61
   * q</code>.
60
   */
62
   */
61
  private final BigInteger x;
63
  private final BigInteger x;
62
64
63
  /** String representation of this key. Cached for speed. */
65
  /** String representation of this key. Cached for speed. */
64
  private transient String str;
66
  private transient String str;
65
67
66
  // Constructor(s)
67
  // -------------------------------------------------------------------------
68
69
  /**
68
  /**
70
   * Convenience constructor. Calls the constructor with 5 arguments passing
69
   * Convenience constructor. Calls the constructor with 5 arguments passing
71
   * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
70
   * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
Lines 100-112 Link Here
100
    super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.PKCS8_ENCODING_ID
99
    super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.PKCS8_ENCODING_ID
101
                                                       : preferredFormat,
100
                                                       : preferredFormat,
102
          p, q, g);
101
          p, q, g);
103
104
    this.x = x;
102
    this.x = x;
105
  }
103
  }
106
104
107
  // Class methods
108
  // -------------------------------------------------------------------------
109
110
  /**
105
  /**
111
   * A class method that takes the output of the <code>encodePrivateKey()</code>
106
   * A class method that takes the output of the <code>encodePrivateKey()</code>
112
   * method of a DSS keypair codec object (an instance implementing
107
   * method of a DSS keypair codec object (an instance implementing
Lines 131-160 Link Here
131
      catch (IllegalArgumentException ignored)
126
      catch (IllegalArgumentException ignored)
132
        {
127
        {
133
        }
128
        }
134
135
    // try PKCS#8 codec
129
    // try PKCS#8 codec
136
    return (DSSPrivateKey) new DSSKeyPairPKCS8Codec().decodePrivateKey(k);
130
    return (DSSPrivateKey) new DSSKeyPairPKCS8Codec().decodePrivateKey(k);
137
  }
131
  }
138
132
139
  // Instance methods
140
  // -------------------------------------------------------------------------
141
142
  // java.security.interfaces.DSAPrivateKey interface implementation ---------
143
144
  public BigInteger getX()
133
  public BigInteger getX()
145
  {
134
  {
146
    return x;
135
    return x;
147
  }
136
  }
148
137
149
  // Other instance methods --------------------------------------------------
150
151
  /**
138
  /**
152
   * <p>Returns the encoded form of this private key according to the
139
   * Returns the encoded form of this private key according to the designated
153
   * designated format.</p>
140
   * format.
154
   *
141
   * 
155
   * @param format the desired format identifier of the resulting encoding.
142
   * @param format the desired format identifier of the resulting encoding.
156
   * @return the byte sequence encoding this key according to the designated
143
   * @return the byte sequence encoding this key according to the designated
157
   * format.
144
   *         format.
158
   * @exception IllegalArgumentException if the format is not supported.
145
   * @exception IllegalArgumentException if the format is not supported.
159
   * @see DSSKeyPairRawCodec
146
   * @see DSSKeyPairRawCodec
160
   */
147
   */
Lines 177-200 Link Here
177
  }
164
  }
178
165
179
  /**
166
  /**
180
   * <p>Returns <code>true</code> if the designated object is an instance of
167
   * Returns <code>true</code> if the designated object is an instance of
181
   * {@link DSAPrivateKey} and has the same DSS (Digital Signature Standard)
168
   * {@link DSAPrivateKey} and has the same DSS (Digital Signature Standard)
182
   * parameter values as this one.</p>
169
   * parameter values as this one.
183
   *
170
   * 
184
   * @param obj the other non-null DSS key to compare to.
171
   * @param obj the other non-null DSS key to compare to.
185
   * @return <code>true</code> if the designated object is of the same type and
172
   * @return <code>true</code> if the designated object is of the same type
186
   * value as this one.
173
   *         and value as this one.
187
   */
174
   */
188
  public boolean equals(Object obj)
175
  public boolean equals(Object obj)
189
  {
176
  {
190
    if (obj == null)
177
    if (obj == null)
191
      {
178
      return false;
192
        return false;
179
193
      }
180
    if (! (obj instanceof DSAPrivateKey))
194
    if (!(obj instanceof DSAPrivateKey))
181
      return false;
195
      {
182
196
        return false;
197
      }
198
    DSAPrivateKey that = (DSAPrivateKey) obj;
183
    DSAPrivateKey that = (DSAPrivateKey) obj;
199
    return super.equals(that) && x.equals(that.getX());
184
    return super.equals(that) && x.equals(that.getX());
200
  }
185
  }
Lines 205-216 Link Here
205
      {
190
      {
206
        String ls = SystemProperties.getProperty("line.separator");
191
        String ls = SystemProperties.getProperty("line.separator");
207
        str = new StringBuilder(this.getClass().getName()).append("(")
192
        str = new StringBuilder(this.getClass().getName()).append("(")
208
        .append(super.toString()).append(",").append(ls)
193
            .append(super.toString()).append(",").append(ls)
209
        .append("x=0x").append(Configuration.DEBUG ? x.toString(16)
194
            .append("x=0x").append(Configuration.DEBUG ? x.toString(16)
210
                                                   : "**...*").append(ls)
195
                                                       : "**...*").append(ls)
211
        .append(")").toString();
196
            .append(")")
197
            .toString();
212
      }
198
      }
213
214
    return str;
199
    return str;
215
  }
200
  }
216
}
201
}
(-)dss/DSSPublicKey.java (-42 / +24 lines)
Lines 47-73 Link Here
47
import java.security.interfaces.DSAPublicKey;
47
import java.security.interfaces.DSAPublicKey;
48
48
49
/**
49
/**
50
 * <p>An object that embodies a DSS (Digital Signature Standard) public key.</p>
50
 * An object that embodies a DSS (Digital Signature Standard) public key.
51
 * 
51
 * 
52
 * @see #getEncoded
52
 * @see #getEncoded
53
 */
53
 */
54
public class DSSPublicKey extends DSSKey implements PublicKey, DSAPublicKey
54
public class DSSPublicKey
55
    extends DSSKey
56
    implements PublicKey, DSAPublicKey
55
{
57
{
56
  // Constants and variables
57
  // -------------------------------------------------------------------------
58
59
  /**
58
  /**
60
   * <code>y = g<sup>x</sup> mod p</code> where <code>x</code> is the private
59
   * <code>y = g<sup>x</sup> mod p</code> where <code>x</code> is the
61
   * part of the DSA key.
60
   * private part of the DSA key.
62
   */
61
   */
63
  private final BigInteger y;
62
  private final BigInteger y;
64
63
65
  /** String representation of this key. Cached for speed. */
64
  /** String representation of this key. Cached for speed. */
66
  private transient String str;
65
  private transient String str;
67
66
68
  // Constructor(s)
69
  // -------------------------------------------------------------------------
70
71
  /**
67
  /**
72
   * Conveience constructor. Calls the constructor with 5 arguments passing
68
   * Conveience constructor. Calls the constructor with 5 arguments passing
73
   * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
69
   * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
Lines 85-92 Link Here
85
  }
81
  }
86
82
87
  /**
83
  /**
88
   * Constructs a new instance of <code>DSSPublicKey</code> given the designated
84
   * Constructs a new instance of <code>DSSPublicKey</code> given the
89
   * arguments.
85
   * designated arguments.
90
   * 
86
   * 
91
   * @param preferredFormat the identifier of the preferred encoding format to
87
   * @param preferredFormat the identifier of the preferred encoding format to
92
   *          use when externalizing this key.
88
   *          use when externalizing this key.
Lines 102-114 Link Here
102
    super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.X509_ENCODING_ID
98
    super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.X509_ENCODING_ID
103
                                                       : preferredFormat,
99
                                                       : preferredFormat,
104
          p, q, g);
100
          p, q, g);
105
106
    this.y = y;
101
    this.y = y;
107
  }
102
  }
108
103
109
  // Class methods
110
  // -------------------------------------------------------------------------
111
112
  /**
104
  /**
113
   * A class method that takes the output of the <code>encodePublicKey()</code>
105
   * A class method that takes the output of the <code>encodePublicKey()</code>
114
   * method of a DSS keypair codec object (an instance implementing
106
   * method of a DSS keypair codec object (an instance implementing
Lines 133-162 Link Here
133
      catch (IllegalArgumentException ignored)
125
      catch (IllegalArgumentException ignored)
134
        {
126
        {
135
        }
127
        }
136
137
    // try X.509 codec
128
    // try X.509 codec
138
    return (DSSPublicKey) new DSSKeyPairX509Codec().decodePublicKey(k);
129
    return (DSSPublicKey) new DSSKeyPairX509Codec().decodePublicKey(k);
139
  }
130
  }
140
131
141
  // Instance methods
142
  // -------------------------------------------------------------------------
143
144
  // java.security.interfaces.DSAPublicKey interface implementation ----------
145
146
  public BigInteger getY()
132
  public BigInteger getY()
147
  {
133
  {
148
    return y;
134
    return y;
149
  }
135
  }
150
136
151
  // Other instance methods --------------------------------------------------
152
153
  /**
137
  /**
154
   * <p>Returns the encoded form of this public key according to the designated
138
   * Returns the encoded form of this public key according to the designated
155
   * format.</p>
139
   * format.
156
   * 
140
   * 
157
   * @param format the desired format identifier of the resulting encoding.
141
   * @param format the desired format identifier of the resulting encoding.
158
   * @return the byte sequence encoding this key according to the designated
142
   * @return the byte sequence encoding this key according to the designated
159
   * format.
143
   *         format.
160
   * @exception IllegalArgumentException if the format is not supported.
144
   * @exception IllegalArgumentException if the format is not supported.
161
   * @see DSSKeyPairRawCodec
145
   * @see DSSKeyPairRawCodec
162
   */
146
   */
Lines 179-202 Link Here
179
  }
163
  }
180
164
181
  /**
165
  /**
182
   * <p>Returns <code>true</code> if the designated object is an instance of
166
   * Returns <code>true</code> if the designated object is an instance of
183
   * {@link DSAPublicKey} and has the same DSS (Digital Signature Standard)
167
   * {@link DSAPublicKey} and has the same DSS (Digital Signature Standard)
184
   * parameter values as this one.</p>
168
   * parameter values as this one.
185
   * 
169
   * 
186
   * @param obj the other non-null DSS key to compare to.
170
   * @param obj the other non-null DSS key to compare to.
187
   * @return <code>true</code> if the designated object is of the same type and
171
   * @return <code>true</code> if the designated object is of the same type
188
   * value as this one.
172
   *         and value as this one.
189
   */
173
   */
190
  public boolean equals(Object obj)
174
  public boolean equals(Object obj)
191
  {
175
  {
192
    if (obj == null)
176
    if (obj == null)
193
      {
177
      return false;
194
        return false;
178
195
      }
179
    if (! (obj instanceof DSAPublicKey))
196
    if (!(obj instanceof DSAPublicKey))
180
      return false;
197
      {
181
198
        return false;
199
      }
200
    DSAPublicKey that = (DSAPublicKey) obj;
182
    DSAPublicKey that = (DSAPublicKey) obj;
201
    return super.equals(that) && y.equals(that.getY());
183
    return super.equals(that) && y.equals(that.getY());
202
  }
184
  }
Lines 207-217 Link Here
207
      {
189
      {
208
        String ls = SystemProperties.getProperty("line.separator");
190
        String ls = SystemProperties.getProperty("line.separator");
209
        str = new StringBuilder(this.getClass().getName()).append("(")
191
        str = new StringBuilder(this.getClass().getName()).append("(")
210
        .append(super.toString()).append(",").append(ls)
192
            .append(super.toString()).append(",").append(ls)
211
        .append("y=0x").append(y.toString(16)).append(ls)
193
            .append("y=0x").append(y.toString(16)).append(ls)
212
        .append(")").toString();
194
            .append(")")
195
            .toString();
213
      }
196
      }
214
215
    return str;
197
    return str;
216
  }
198
  }
217
}
199
}
(-)dss/FIPS186.java (-67 / +36 lines)
Lines 45-64 Link Here
45
import java.security.SecureRandom;
45
import java.security.SecureRandom;
46
46
47
/**
47
/**
48
 * <p>An implementation of the DSA parameters generation as described in
48
 * An implementation of the DSA parameters generation as described in FIPS-186.
49
 * FIPS-186.</p>
49
 * <p>
50
 *
50
 * References:
51
 * References:<br>
51
 * <p>
52
 * <a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature
52
 * <a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature
53
 * Standard (DSS)</a>, Federal Information Processing Standards Publication 186.
53
 * Standard (DSS)</a>, Federal Information Processing Standards Publication
54
 * National Institute of Standards and Technology.
54
 * 186. National Institute of Standards and Technology.
55
 */
55
 */
56
public class FIPS186
56
public class FIPS186
57
{
57
{
58
59
  // Constants and variables
60
  // -------------------------------------------------------------------------
61
62
  public static final int DSA_PARAMS_SEED = 0;
58
  public static final int DSA_PARAMS_SEED = 0;
63
59
64
  public static final int DSA_PARAMS_COUNTER = 1;
60
  public static final int DSA_PARAMS_COUNTER = 1;
Lines 72-78 Link Here
72
  public static final int DSA_PARAMS_G = 5;
68
  public static final int DSA_PARAMS_G = 5;
73
69
74
  /** The BigInteger constant 2. */
70
  /** The BigInteger constant 2. */
75
  private static final BigInteger TWO = new BigInteger("2");
71
  private static final BigInteger TWO = BigInteger.valueOf(2L);
76
72
77
  private static final BigInteger TWO_POW_160 = TWO.pow(160);
73
  private static final BigInteger TWO_POW_160 = TWO.pow(160);
78
74
Lines 88-96 Link Here
88
  /** Our default source of randomness. */
84
  /** Our default source of randomness. */
89
  private PRNG prng = null;
85
  private PRNG prng = null;
90
86
91
  // Constructor(s)
92
  // -------------------------------------------------------------------------
93
94
  public FIPS186(int L, SecureRandom rnd)
87
  public FIPS186(int L, SecureRandom rnd)
95
  {
88
  {
96
    super();
89
    super();
Lines 99-136 Link Here
99
    this.rnd = rnd;
92
    this.rnd = rnd;
100
  }
93
  }
101
94
102
  // Class methods
103
  // -------------------------------------------------------------------------
104
105
  // Instance methods
106
  // -------------------------------------------------------------------------
107
108
  /**
95
  /**
109
   * This method generates the DSS <code>p</code>, <code>q</code>, and
96
   * This method generates the DSS <code>p</code>, <code>q</code>, and
110
   * <code>g</code> parameters only when <code>L</code> (the modulus length)
97
   * <code>g</code> parameters only when <code>L</code> (the modulus length)
111
   * is not one of the following: <code>512</code>, <code>768</code> and
98
   * is not one of the following: <code>512</code>, <code>768</code> and
112
   * <code>1024</code>. For those values of <code>L</code>, this implementation
99
   * <code>1024</code>. For those values of <code>L</code>, this
113
   * uses pre-computed values of <code>p</code>, <code>q</code>, and
100
   * implementation uses pre-computed values of <code>p</code>,
114
   * <code>g</code> given in the document <i>CryptoSpec</i> included in the
101
   * <code>q</code>, and <code>g</code> given in the document <i>CryptoSpec</i>
115
   * security guide documentation of the standard JDK distribution.<p>
102
   * included in the security guide documentation of the standard JDK
116
   *
103
   * distribution.
104
   * <p>
117
   * The DSS requires two primes , <code>p</code> and <code>q</code>,
105
   * The DSS requires two primes , <code>p</code> and <code>q</code>,
118
   * satisfying the following three conditions:
106
   * satisfying the following three conditions:
119
   *
120
   * <ul>
107
   * <ul>
121
   *    <li><code>2<sup>159</sup> &lt; q &lt; 2<sup>160</sup></code></li>
108
   * <li><code>2<sup>159</sup> &lt; q &lt; 2<sup>160</sup></code></li>
122
   *    <li><code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code> for a
109
   * <li><code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code> for a
123
   *    specified <code>L</code>, where <code>L = 512 + 64j</code> for some
110
   * specified <code>L</code>, where <code>L = 512 + 64j</code> for some
124
   *    <code>0 &lt;= j &lt;= 8</code></li>
111
   * <code>0 &lt;= j &lt;= 8</code></li>
125
   *    <li>q divides p - 1.</li>
112
   * <li>q divides p - 1.</li>
126
   * </ul>
113
   * </ul>
127
   *
128
   * The algorithm used to find these primes is as described in FIPS-186,
114
   * The algorithm used to find these primes is as described in FIPS-186,
129
   * section 2.2: GENERATION OF PRIMES. This prime generation scheme starts by
115
   * section 2.2: GENERATION OF PRIMES. This prime generation scheme starts by
130
   * using the {@link Sha160} and a user supplied <i>SEED</i>
116
   * using the {@link Sha160} and a user supplied <i>SEED</i> to construct a
131
   * to construct a prime, <code>q</code>, in the range 2<sup>159</sup> &lt; q
117
   * prime, <code>q</code>, in the range 2<sup>159</sup> &lt; q &lt; 2<sup>160</sup>.
132
   * &lt; 2<sup>160</sup>. Once this is accomplished, the same <i>SEED</i>
118
   * Once this is accomplished, the same <i>SEED</i> value is used to construct
133
   * value is used to construct an <code>X</code> in the range <code>2<sup>L-1
119
   * an <code>X</code> in the range <code>2<sup>L-1
134
   * </sup> &lt; X &lt; 2<sup>L</sup>. The prime, <code>p</code>, is then
120
   * </sup> &lt; X &lt; 2<sup>L</sup>. The prime, <code>p</code>, is then
135
   * formed by rounding <code>X</code> to a number congruent to <code>1 mod
121
   * formed by rounding <code>X</code> to a number congruent to <code>1 mod
136
   * 2q</code>. In this implementation we use the same <i>SEED</i> value given
122
   * 2q</code>. In this implementation we use the same <i>SEED</i> value given
Lines 168-176 Link Here
168
                u = sha.digest();
154
                u = sha.digest();
169
              }
155
              }
170
            for (int i = 0; i < a.length; i++)
156
            for (int i = 0; i < a.length; i++)
171
              {
157
              a[i] ^= u[i];
172
                a[i] ^= u[i];
158
173
              }
174
            U = new BigInteger(1, a);
159
            U = new BigInteger(1, a);
175
            // 3. Form q from U by setting the most significant bit (the
160
            // 3. Form q from U by setting the most significant bit (the
176
            // 2**159 bit) and the least significant bit to 1. In terms of
161
            // 2**159 bit) and the least significant bit to 1. In terms of
Lines 183-193 Link Here
183
            // most 1/2**80.
168
            // most 1/2**80.
184
            // 5. If q is not prime, go to step 1.
169
            // 5. If q is not prime, go to step 1.
185
            if (q.isProbablePrime(80))
170
            if (q.isProbablePrime(80))
186
              {
171
              break step1;
187
                break step1;
188
              }
189
          } // step1
172
          } // step1
190
191
        // 6. Let counter = 0 and offset = 2.
173
        // 6. Let counter = 0 and offset = 2.
192
        counter = 0;
174
        counter = 0;
193
        offset = 2;
175
        offset = 2;
Lines 200-208 Link Here
200
              {
182
              {
201
                for (int k = 0; k <= n; k++)
183
                for (int k = 0; k <= n; k++)
202
                  {
184
                  {
203
                    a = SEED_PLUS_OFFSET.add(
185
                    a = SEED_PLUS_OFFSET
204
                                             BigInteger.valueOf(k & 0xFFFFFFFFL)).mod(
186
                        .add(BigInteger.valueOf(k & 0xFFFFFFFFL))
205
                                                                                      TWO_POW_160).toByteArray();
187
                        .mod(TWO_POW_160).toByteArray();
206
                    sha.update(a, 0, a.length);
188
                    sha.update(a, 0, a.length);
207
                    V[k] = new BigInteger(1, sha.digest());
189
                    V[k] = new BigInteger(1, sha.digest());
208
                  }
190
                  }
Lines 213-221 Link Here
213
            // Note that 0 <= W < 2**(L-1) and hence 2**(L-1) <= X < 2**L.
195
            // Note that 0 <= W < 2**(L-1) and hence 2**(L-1) <= X < 2**L.
214
            W = V[0];
196
            W = V[0];
215
            for (int k = 1; k < n; k++)
197
            for (int k = 1; k < n; k++)
216
              {
198
              W = W.add(V[k].multiply(TWO.pow(k * 160)));
217
                W = W.add(V[k].multiply(TWO.pow(k * 160)));
199
218
              }
219
            W = W.add(V[n].mod(TWO.pow(b)).multiply(TWO.pow(n * 160)));
200
            W = W.add(V[n].mod(TWO.pow(b)).multiply(TWO.pow(n * 160)));
220
            X = W.add(TWO.pow(L - 1));
201
            X = W.add(TWO.pow(L - 1));
221
            // 9. Let c = X mod 2q and set p = X - (c - 1).
202
            // 9. Let c = X mod 2q and set p = X - (c - 1).
Lines 228-248 Link Here
228
                // 11. Perform a robust primality test on p.
209
                // 11. Perform a robust primality test on p.
229
                // 12. If p passes the test performed in step 11, go to step 15.
210
                // 12. If p passes the test performed in step 11, go to step 15.
230
                if (p.isProbablePrime(80))
211
                if (p.isProbablePrime(80))
231
                  {
212
                  break algorithm;
232
                    break algorithm;
233
                  }
234
              }
213
              }
235
            // 13. Let counter = counter + 1 and offset = offset + n + 1.
214
            // 13. Let counter = counter + 1 and offset = offset + n + 1.
236
            counter++;
215
            counter++;
237
            offset += n + 1;
216
            offset += n + 1;
238
            // 14. If counter >= 4096 go to step 1, otherwise go to step 7.
217
            // 14. If counter >= 4096 go to step 1, otherwise go to step 7.
239
            if (counter >= 4096)
218
            if (counter >= 4096)
240
              {
219
              continue algorithm;
241
                continue algorithm;
242
              }
243
          } // step7
220
          } // step7
244
      } // algorithm
221
      } // algorithm
245
246
    // compute g. from FIPS-186, Appendix 4:
222
    // compute g. from FIPS-186, Appendix 4:
247
    // 1. Generate p and q as specified in Appendix 2.
223
    // 1. Generate p and q as specified in Appendix 2.
248
    // 2. Let e = (p - 1) / q
224
    // 2. Let e = (p - 1) / q
Lines 257-284 Link Here
257
        // 4. Set g = h**e mod p
233
        // 4. Set g = h**e mod p
258
        g = h.modPow(e, p);
234
        g = h.modPow(e, p);
259
        // 5. If g = 1, go to step 3
235
        // 5. If g = 1, go to step 3
260
        if (!g.equals(BigInteger.ONE))
236
        if (! g.equals(BigInteger.ONE))
261
          {
237
          break;
262
            break;
263
          }
264
      }
238
      }
265
266
    return new BigInteger[] { SEED, BigInteger.valueOf(counter), q, p, e, g };
239
    return new BigInteger[] { SEED, BigInteger.valueOf(counter), q, p, e, g };
267
  }
240
  }
268
241
269
  // helper methods ----------------------------------------------------------
270
271
  /**
242
  /**
272
   * Fills the designated byte array with random data.
243
   * Fills the designated byte array with random data.
273
   *
244
   * 
274
   * @param buffer the byte array to fill with random data.
245
   * @param buffer the byte array to fill with random data.
275
   */
246
   */
276
  private void nextRandomBytes(byte[] buffer)
247
  private void nextRandomBytes(byte[] buffer)
277
  {
248
  {
278
    if (rnd != null)
249
    if (rnd != null)
279
      {
250
      rnd.nextBytes(buffer);
280
        rnd.nextBytes(buffer);
281
      }
282
    else
251
    else
283
      getDefaultPRNG().nextBytes(buffer);
252
      getDefaultPRNG().nextBytes(buffer);
284
  }
253
  }
(-)rsa/GnuRSAKey.java (-44 / +22 lines)
Lines 47-60 Link Here
47
import java.security.interfaces.RSAKey;
47
import java.security.interfaces.RSAKey;
48
48
49
/**
49
/**
50
 * <p>A base asbtract class for both public and private RSA keys.</p>
50
 * A base asbtract class for both public and private RSA keys.
51
 */
51
 */
52
public abstract class GnuRSAKey implements Key, RSAKey
52
public abstract class GnuRSAKey
53
    implements Key, RSAKey
53
{
54
{
54
55
  // Constants and variables
56
  // -------------------------------------------------------------------------
57
58
  /** The public modulus of an RSA key pair. */
55
  /** The public modulus of an RSA key pair. */
59
  private final BigInteger n;
56
  private final BigInteger n;
60
57
Lines 62-78 Link Here
62
  private final BigInteger e;
59
  private final BigInteger e;
63
60
64
  /**
61
  /**
65
   * Identifier of the default encoding format to use when externalizing the
62
   * Identifier of the default encoding format to use when externalizing the key
66
   * key material.
63
   * material.
67
   */
64
   */
68
  protected final int defaultFormat;
65
  protected final int defaultFormat;
69
66
70
  /** String representation of this key. Cached for speed. */
67
  /** String representation of this key. Cached for speed. */
71
  private transient String str;
68
  private transient String str;
72
69
73
  // Constructor(s)
74
  // -------------------------------------------------------------------------
75
76
  /**
70
  /**
77
   * Trivial protected constructor.
71
   * Trivial protected constructor.
78
   * 
72
   * 
Lines 91-111 Link Here
91
    this.e = e;
85
    this.e = e;
92
  }
86
  }
93
87
94
  // Class methods
95
  // -------------------------------------------------------------------------
96
97
  // Instance methods
98
  // -------------------------------------------------------------------------
99
100
  // java.security.interfaces.RSAKey interface implementation ----------------
101
102
  public BigInteger getModulus()
88
  public BigInteger getModulus()
103
  {
89
  {
104
    return getN();
90
    return getN();
105
  }
91
  }
106
92
107
  // java.security.Key interface implementation ------------------------------
108
109
  public String getAlgorithm()
93
  public String getAlgorithm()
110
  {
94
  {
111
    return Registry.RSA_KPG;
95
    return Registry.RSA_KPG;
Lines 122-132 Link Here
122
    return FormatUtil.getEncodingShortName(defaultFormat);
106
    return FormatUtil.getEncodingShortName(defaultFormat);
123
  }
107
  }
124
108
125
  // Other instance methods --------------------------------------------------
126
127
  /**
109
  /**
128
   * <p>Returns the modulus <code>n</code>.</p>
110
   * Returns the modulus <code>n</code>.
129
   *
111
   * 
130
   * @return the modulus <code>n</code>.
112
   * @return the modulus <code>n</code>.
131
   */
113
   */
132
  public BigInteger getN()
114
  public BigInteger getN()
Lines 135-142 Link Here
135
  }
117
  }
136
118
137
  /**
119
  /**
138
   * <p>Returns the public exponent <code>e</code>.</p>
120
   * Returns the public exponent <code>e</code>.
139
   *
121
   * 
140
   * @return the public exponent <code>e</code>.
122
   * @return the public exponent <code>e</code>.
141
   */
123
   */
142
  public BigInteger getPublicExponent()
124
  public BigInteger getPublicExponent()
Lines 145-152 Link Here
145
  }
127
  }
146
128
147
  /**
129
  /**
148
   * <p>Same as {@link #getPublicExponent()}.</p>
130
   * Same as {@link #getPublicExponent()}.
149
   *
131
   * 
150
   * @return the public exponent <code>e</code>.
132
   * @return the public exponent <code>e</code>.
151
   */
133
   */
152
  public BigInteger getE()
134
  public BigInteger getE()
Lines 155-177 Link Here
155
  }
137
  }
156
138
157
  /**
139
  /**
158
   * <p>Returns <code>true</code> if the designated object is an instance of
140
   * Returns <code>true</code> if the designated object is an instance of
159
   * {@link RSAKey} and has the same RSA parameter values as this one.</p>
141
   * {@link RSAKey} and has the same RSA parameter values as this one.
160
   *
142
   * 
161
   * @param obj the other non-null RSA key to compare to.
143
   * @param obj the other non-null RSA key to compare to.
162
   * @return <code>true</code> if the designated object is of the same type and
144
   * @return <code>true</code> if the designated object is of the same type
163
   * value as this one.
145
   *         and value as this one.
164
   */
146
   */
165
  public boolean equals(final Object obj)
147
  public boolean equals(final Object obj)
166
  {
148
  {
167
    if (obj == null)
149
    if (obj == null)
168
      {
150
      return false;
169
        return false;
151
170
      }
152
    if (! (obj instanceof RSAKey))
171
    if (!(obj instanceof RSAKey))
153
      return false;
172
      {
154
173
        return false;
174
      }
175
    final RSAKey that = (RSAKey) obj;
155
    final RSAKey that = (RSAKey) obj;
176
    return n.equals(that.getModulus());
156
    return n.equals(that.getModulus());
177
  }
157
  }
Lines 181-187 Link Here
181
    if (str == null)
161
    if (str == null)
182
      {
162
      {
183
        String ls = SystemProperties.getProperty("line.separator");
163
        String ls = SystemProperties.getProperty("line.separator");
184
        str = new StringBuilder().append(ls)
164
        str = new StringBuilder(ls)
185
            .append("defaultFormat=").append(defaultFormat).append(",").append(ls)
165
            .append("defaultFormat=").append(defaultFormat).append(",").append(ls)
186
            .append("n=0x").append(n.toString(16)).append(",").append(ls)
166
            .append("n=0x").append(n.toString(16)).append(",").append(ls)
187
            .append("e=0x").append(e.toString(16))
167
            .append("e=0x").append(e.toString(16))
Lines 190-196 Link Here
190
    return str;
170
    return str;
191
  }
171
  }
192
172
193
  // abstract methods to be implemented by subclasses ------------------------
194
195
  public abstract byte[] getEncoded(int format);
173
  public abstract byte[] getEncoded(int format);
196
}
174
}
(-)rsa/GnuRSAPrivateKey.java (-51 / +38 lines)
Lines 49-66 Link Here
49
import java.security.interfaces.RSAPrivateKey;
49
import java.security.interfaces.RSAPrivateKey;
50
50
51
/**
51
/**
52
 * <p>An object that embodies an RSA private key.</p>
52
 * An object that embodies an RSA private key.
53
 *
53
 * <p>
54
 * <p>References:</p>
54
 * References:
55
 * <ol>
55
 * <ol>
56
 *    <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
56
 * <li><a
57
 *    RSA-PSS Signature Scheme with Appendix, part B.</a><br>
57
 * href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
58
 *    Primitive specification and supporting documentation.<br>
58
 * RSA-PSS Signature Scheme with Appendix, part B.</a><br>
59
 *    Jakob Jonsson and Burt Kaliski.</li>
59
 * Primitive specification and supporting documentation.<br>
60
 * Jakob Jonsson and Burt Kaliski.</li>
60
 * </ol>
61
 * </ol>
61
 */
62
 */
62
public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
63
public class GnuRSAPrivateKey
63
    RSAPrivateCrtKey
64
    extends GnuRSAKey
65
    implements PrivateKey, RSAPrivateCrtKey
64
{
66
{
65
  /** The first prime divisor of the modulus. */
67
  /** The first prime divisor of the modulus. */
66
  private final BigInteger p;
68
  private final BigInteger p;
Lines 68-75 Link Here
68
  /** The second prime divisor of the modulus. */
70
  /** The second prime divisor of the modulus. */
69
  private final BigInteger q;
71
  private final BigInteger q;
70
72
71
  /** The public exponent of an RSA key. */
72
  //   private final BigInteger e;
73
  /** The private exponent of an RSA private key. */
73
  /** The private exponent of an RSA private key. */
74
  private final BigInteger d;
74
  private final BigInteger d;
75
75
Lines 85-105 Link Here
85
  /** String representation of this key. Cached for speed. */
85
  /** String representation of this key. Cached for speed. */
86
  private transient String str;
86
  private transient String str;
87
87
88
  // Constructor(s)
89
  // -------------------------------------------------------------------------
90
91
  /**
88
  /**
92
   * Convenience constructor. Calls the constructor with 5 arguments passing
89
   * Convenience constructor. Calls the constructor with 5 arguments passing
93
   * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
90
   * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
94
   * encoding format.
91
   * encoding format.
95
   *
92
   * 
96
   * @param p the modulus first prime divisor.
93
   * @param p the modulus first prime divisor.
97
   * @param q the modulus second prime divisor.
94
   * @param q the modulus second prime divisor.
98
   * @param e the public exponent.
95
   * @param e the public exponent.
99
   * @param d the private exponent.
96
   * @param d the private exponent.
100
   */
97
   */
101
  public GnuRSAPrivateKey(BigInteger p, BigInteger q, BigInteger e,
98
  public GnuRSAPrivateKey(BigInteger p, BigInteger q, BigInteger e, BigInteger d)
102
                          BigInteger d)
103
  {
99
  {
104
    this(Registry.RAW_ENCODING_ID, p, q, e, d);
100
    this(Registry.RAW_ENCODING_ID, p, q, e, d);
105
  }
101
  }
Lines 118-124 Link Here
118
  public GnuRSAPrivateKey(int preferredFormat, BigInteger p, BigInteger q,
114
  public GnuRSAPrivateKey(int preferredFormat, BigInteger p, BigInteger q,
119
                          BigInteger e, BigInteger d)
115
                          BigInteger e, BigInteger d)
120
  {
116
  {
121
    this(preferredFormat, p.multiply(q), e, d, p, q, 
117
    this(preferredFormat,
118
         p.multiply(q),
119
         e, d, p, q,
122
         e.modInverse(p.subtract(BigInteger.ONE)),
120
         e.modInverse(p.subtract(BigInteger.ONE)),
123
         e.modInverse(q.subtract(BigInteger.ONE)),
121
         e.modInverse(q.subtract(BigInteger.ONE)),
124
         q.modInverse(p));
122
         q.modInverse(p));
Lines 131-149 Link Here
131
   * @param preferredFormat the indetifier of the preferred encoding format to
129
   * @param preferredFormat the indetifier of the preferred encoding format to
132
   *          use when externalizing this key.
130
   *          use when externalizing this key.
133
   * @param n the public modulus, which is also the product of <code>p</code>
131
   * @param n the public modulus, which is also the product of <code>p</code>
134
   * and <code>q</code>.
132
   *          and <code>q</code>.
135
   * @param e the public exponent.
133
   * @param e the public exponent.
136
   * @param d the private exponent.
134
   * @param d the private exponent.
137
   * @param p the modulus first prime divisor.
135
   * @param p the modulus first prime divisor.
138
   * @param q the modulus second prime divisor.
136
   * @param q the modulus second prime divisor.
139
   * @param dP the first prime's exponen. A positive integer less than
137
   * @param dP the first prime's exponen. A positive integer less than
140
   * <code>p</code> and <code>q</code>, satisfying <code>e * dP = 1 (mod p-1)
138
   *          <code>p</code> and <code>q</code>, satisfying
141
   * </code>.
139
   *          <code>e * dP = 1 (mod p-1)</code>.
142
   * @param dQ the second prime's exponent. A positive integer less than
140
   * @param dQ the second prime's exponent. A positive integer less than
143
   * <code>p</code> and <code>q</code>, satisfying <code>e * dQ = 1 (mod p-1)
141
   *          <code>p</code> and <code>q</code>, satisfying
144
   * </code>.
142
   *          <code>e * dQ = 1 (mod p-1)</code>.
145
   * @param qInv the Chinese Remainder Theorem coefiicient. A positive integer
143
   * @param qInv the Chinese Remainder Theorem coefiicient. A positive integer
146
   * less than <code>p</code>, satisfying <code>q * qInv = 1 (mod p)</code>.
144
   *          less than <code>p</code>, satisfying
145
   *          <code>q * qInv = 1 (mod p)</code>.
147
   */
146
   */
148
  public GnuRSAPrivateKey(int preferredFormat, BigInteger n, BigInteger e,
147
  public GnuRSAPrivateKey(int preferredFormat, BigInteger n, BigInteger e,
149
                          BigInteger d, BigInteger p, BigInteger q,
148
                          BigInteger d, BigInteger p, BigInteger q,
Lines 152-175 Link Here
152
    super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.PKCS8_ENCODING_ID
151
    super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.PKCS8_ENCODING_ID
153
                                                       : preferredFormat,
152
                                                       : preferredFormat,
154
          n, e);
153
          n, e);
155
156
    this.d = d;
154
    this.d = d;
157
    this.p = p;
155
    this.p = p;
158
    this.q = q;
156
    this.q = q;
159
    // the exponents dP and dQ are positive integers less than p and q
157
    // the exponents dP and dQ are positive integers less than p and q
160
    // respectively satisfying
158
    // respectively satisfying
161
    //    e * dP = 1 (mod p-1);
159
    // e * dP = 1 (mod p-1);
162
    //    e * dQ = 1 (mod q-1),
160
    // e * dQ = 1 (mod q-1),
163
    this.dP = dP;
161
    this.dP = dP;
164
    this.dQ = dQ;
162
    this.dQ = dQ;
165
    // the CRT coefficient qInv is a positive integer less than p satisfying
163
    // the CRT coefficient qInv is a positive integer less than p satisfying
166
    //    q * qInv = 1 (mod p).
164
    // q * qInv = 1 (mod p).
167
    this.qInv = qInv;
165
    this.qInv = qInv;
168
  }
166
  }
169
167
170
  // Class methods
171
  // -------------------------------------------------------------------------
172
173
  /**
168
  /**
174
   * A class method that takes the output of the <code>encodePrivateKey()</code>
169
   * A class method that takes the output of the <code>encodePrivateKey()</code>
175
   * method of an RSA keypair codec object (an instance implementing
170
   * method of an RSA keypair codec object (an instance implementing
Lines 194-207 Link Here
194
      catch (IllegalArgumentException ignored)
189
      catch (IllegalArgumentException ignored)
195
        {
190
        {
196
        }
191
        }
197
198
    // try PKCS#8 codec
192
    // try PKCS#8 codec
199
    return (GnuRSAPrivateKey) new RSAKeyPairPKCS8Codec().decodePrivateKey(k);
193
    return (GnuRSAPrivateKey) new RSAKeyPairPKCS8Codec().decodePrivateKey(k);
200
  }
194
  }
201
195
202
  // Instance methods
203
  // -------------------------------------------------------------------------
204
205
  public BigInteger getPrimeP()
196
  public BigInteger getPrimeP()
206
  {
197
  {
207
    return p;
198
    return p;
Lines 227-248 Link Here
227
    return qInv;
218
    return qInv;
228
  }
219
  }
229
220
230
  // java.security.interfaces.RSAPrivateKey interface implementation ---------
231
232
  public BigInteger getPrivateExponent()
221
  public BigInteger getPrivateExponent()
233
  {
222
  {
234
    return d;
223
    return d;
235
  }
224
  }
236
225
237
  // Other instance methods --------------------------------------------------
238
239
  /**
226
  /**
240
   * Returns the encoded form of this private key according to the
227
   * Returns the encoded form of this private key according to the designated
241
   * designated format.
228
   * format.
242
   *
229
   * 
243
   * @param format the desired format identifier of the resulting encoding.
230
   * @param format the desired format identifier of the resulting encoding.
244
   * @return the byte sequence encoding this key according to the designated
231
   * @return the byte sequence encoding this key according to the designated
245
   * format.
232
   *         format.
246
   * @throws IllegalArgumentException if the format is not supported.
233
   * @throws IllegalArgumentException if the format is not supported.
247
   * @see RSAKeyPairRawCodec
234
   * @see RSAKeyPairRawCodec
248
   * @see RSAKeyPairPKCS8Codec
235
   * @see RSAKeyPairPKCS8Codec
Lines 266-284 Link Here
266
  }
253
  }
267
254
268
  /**
255
  /**
269
   * <p>Returns <code>true</code> if the designated object is an instance of
256
   * Returns <code>true</code> if the designated object is an instance of this
270
   * this class and has the same RSA parameter values as this one.</p>
257
   * class and has the same RSA parameter values as this one.
271
   *
258
   * 
272
   * @param obj the other non-null RSA key to compare to.
259
   * @param obj the other non-null RSA key to compare to.
273
   * @return <code>true</code> if the designated object is of the same type
260
   * @return <code>true</code> if the designated object is of the same type
274
   * and value as this one.
261
   *         and value as this one.
275
   */
262
   */
276
  public boolean equals(final Object obj)
263
  public boolean equals(final Object obj)
277
  {
264
  {
278
    if (obj == null)
265
    if (obj == null)
279
      {
266
      return false;
280
        return false;
267
281
      }
282
    if (obj instanceof RSAPrivateKey)
268
    if (obj instanceof RSAPrivateKey)
283
      {
269
      {
284
        final RSAPrivateKey that = (RSAPrivateKey) obj;
270
        final RSAPrivateKey that = (RSAPrivateKey) obj;
Lines 315-321 Link Here
315
                                                        : "**...*").append(ls)
301
                                                        : "**...*").append(ls)
316
            .append("qInv=0x").append(Configuration.DEBUG ? qInv.toString(16)
302
            .append("qInv=0x").append(Configuration.DEBUG ? qInv.toString(16)
317
                                                          : "**...*").append(ls)
303
                                                          : "**...*").append(ls)
318
            .append(")").toString();
304
            .append(")")
305
            .toString();
319
      }
306
      }
320
    return str;
307
    return str;
321
  }
308
  }
(-)rsa/GnuRSAPublicKey.java (-40 / +28 lines)
Lines 47-79 Link Here
47
import java.security.interfaces.RSAPublicKey;
47
import java.security.interfaces.RSAPublicKey;
48
48
49
/**
49
/**
50
 * <p>An object that encapsulates an RSA public key.</p>
50
 * An object that encapsulates an RSA public key.
51
 *
51
 * <p>
52
 * <p>References:</p>
52
 * References:
53
 * <ol>
53
 * <ol>
54
 *    <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
54
 * <li><a
55
 *    RSA-PSS Signature Scheme with Appendix, part B.</a><br>
55
 * href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
56
 *    Primitive specification and supporting documentation.<br>
56
 * RSA-PSS Signature Scheme with Appendix, part B.</a><br>
57
 *    Jakob Jonsson and Burt Kaliski.</li>
57
 * Primitive specification and supporting documentation.<br>
58
 * Jakob Jonsson and Burt Kaliski.</li>
58
 * </ol>
59
 * </ol>
59
 */
60
 */
60
public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey,
61
public class GnuRSAPublicKey
61
    RSAPublicKey
62
    extends GnuRSAKey
63
    implements PublicKey, RSAPublicKey
62
{
64
{
63
  // Constants and variables
64
  // -------------------------------------------------------------------------
65
66
  /** String representation of this key. Cached for speed. */
65
  /** String representation of this key. Cached for speed. */
67
  private transient String str;
66
  private transient String str;
68
67
69
  // Constructor(s)
70
  // -------------------------------------------------------------------------
71
72
  /**
68
  /**
73
   * Conveience constructor. Calls the constructor with 3 arguments passing
69
   * Conveience constructor. Calls the constructor with 3 arguments passing
74
   * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
70
   * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
75
   * encoding format.
71
   * encoding format.
76
   *
72
   * 
77
   * @param n the modulus.
73
   * @param n the modulus.
78
   * @param e the public exponent.
74
   * @param e the public exponent.
79
   */
75
   */
Lines 98-106 Link Here
98
          n, e);
94
          n, e);
99
  }
95
  }
100
96
101
  // Class methods
102
  // -------------------------------------------------------------------------
103
104
  /**
97
  /**
105
   * A class method that takes the output of the <code>encodePublicKey()</code>
98
   * A class method that takes the output of the <code>encodePublicKey()</code>
106
   * method of an RSA keypair codec object (an instance implementing
99
   * method of an RSA keypair codec object (an instance implementing
Lines 125-145 Link Here
125
      catch (IllegalArgumentException ignored)
118
      catch (IllegalArgumentException ignored)
126
        {
119
        {
127
        }
120
        }
128
129
    // try X.509 codec
121
    // try X.509 codec
130
    return (GnuRSAPublicKey) new RSAKeyPairX509Codec().decodePublicKey(k);
122
    return (GnuRSAPublicKey) new RSAKeyPairX509Codec().decodePublicKey(k);
131
  }
123
  }
132
124
133
  // Instance methods
134
  // -------------------------------------------------------------------------
135
136
  /**
125
  /**
137
   * <p>Returns the encoded form of this public key according to the designated
126
   * Returns the encoded form of this public key according to the designated
138
   * format.</p>
127
   * format.
139
   *
128
   * 
140
   * @param format the desired format identifier of the resulting encoding.
129
   * @param format the desired format identifier of the resulting encoding.
141
   * @return the byte sequence encoding this key according to the designated
130
   * @return the byte sequence encoding this key according to the designated
142
   * format.
131
   *         format.
143
   * @throws IllegalArgumentException if the format is not supported.
132
   * @throws IllegalArgumentException if the format is not supported.
144
   * @see RSAKeyPairRawCodec
133
   * @see RSAKeyPairRawCodec
145
   */
134
   */
Lines 162-184 Link Here
162
  }
151
  }
163
152
164
  /**
153
  /**
165
   * <p>Returns <code>true</code> if the designated object is an instance of
154
   * Returns <code>true</code> if the designated object is an instance of this
166
   * this class and has the same RSA parameter values as this one.</p>
155
   * class and has the same RSA parameter values as this one.
167
   *
156
   * 
168
   * @param obj the other non-null RSA key to compare to.
157
   * @param obj the other non-null RSA key to compare to.
169
   * @return <code>true</code> if the designated object is of the same type and
158
   * @return <code>true</code> if the designated object is of the same type
170
   * value as this one.
159
   *         and value as this one.
171
   */
160
   */
172
  public boolean equals(final Object obj)
161
  public boolean equals(final Object obj)
173
  {
162
  {
174
    if (obj == null)
163
    if (obj == null)
175
      {
164
      return false;
176
        return false;
165
177
      }
166
    if (! (obj instanceof RSAPublicKey))
178
    if (!(obj instanceof RSAPublicKey))
167
      return false;
179
      {
168
180
        return false;
181
      }
182
    final RSAPublicKey that = (RSAPublicKey) obj;
169
    final RSAPublicKey that = (RSAPublicKey) obj;
183
    return super.equals(that)
170
    return super.equals(that)
184
           && getPublicExponent().equals(that.getPublicExponent());
171
           && getPublicExponent().equals(that.getPublicExponent());
Lines 191-197 Link Here
191
        String ls = SystemProperties.getProperty("line.separator");
178
        String ls = SystemProperties.getProperty("line.separator");
192
        str = new StringBuilder(this.getClass().getName()).append("(")
179
        str = new StringBuilder(this.getClass().getName()).append("(")
193
            .append(super.toString()).append(",").append(ls)
180
            .append(super.toString()).append(",").append(ls)
194
            .append(")").toString();
181
            .append(")")
182
            .toString();
195
      }
183
      }
196
    return str;
184
    return str;
197
  }
185
  }
(-)rsa/RSAKeyPairGenerator.java (-61 / +31 lines)
Lines 53-77 Link Here
53
import java.util.logging.Logger;
53
import java.util.logging.Logger;
54
54
55
/**
55
/**
56
 * <p>A key-pair generator for asymetric keys to use in conjunction with the RSA
56
 * A key-pair generator for asymetric keys to use in conjunction with the RSA
57
 * scheme.</p>
57
 * scheme.
58
 *
58
 * <p>
59
 * <p>Reference:</p>
59
 * Reference:
60
 * <ol>
60
 * <ol>
61
 *    <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
61
 * <li><a
62
 *    RSA-PSS Signature Scheme with Appendix</a>, part B. Primitive
62
 * href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
63
 *    specification and supporting documentation. Jakob Jonsson and Burt Kaliski.
63
 * RSA-PSS Signature Scheme with Appendix</a>, part B. Primitive specification
64
 *    </li>
64
 * and supporting documentation. Jakob Jonsson and Burt Kaliski. </li>
65
 *    <li><a href="http://www.cacr.math.uwaterloo.ca/hac/">Handbook of Applied
65
 * <li><a href="http://www.cacr.math.uwaterloo.ca/hac/">Handbook of Applied
66
 *    Cryptography</a>, Alfred J. Menezes, Paul C. van Oorschot and Scott A.
66
 * Cryptography</a>, Alfred J. Menezes, Paul C. van Oorschot and Scott A.
67
 *    Vanstone. Section 11.3 RSA and related signature schemes.</li>
67
 * Vanstone. Section 11.3 RSA and related signature schemes.</li>
68
 * </ol>
68
 * </ol>
69
 */
69
 */
70
public class RSAKeyPairGenerator implements IKeyPairGenerator
70
public class RSAKeyPairGenerator
71
    implements IKeyPairGenerator
71
{
72
{
72
  // Constants and variables
73
  // -------------------------------------------------------------------------
74
75
  private static final Logger log = Logger.getLogger(RSAKeyPairGenerator.class.getName());
73
  private static final Logger log = Logger.getLogger(RSAKeyPairGenerator.class.getName());
76
74
77
  /** The BigInteger constant 1. */
75
  /** The BigInteger constant 1. */
Lines 90-97 Link Here
90
  public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.rsa.prng";
88
  public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.rsa.prng";
91
89
92
  /**
90
  /**
93
   * Property name of an optional {@link RSAKeyGenParameterSpec} instance to
91
   * Property name of an optional {@link RSAKeyGenParameterSpec} instance to use
94
   * use for this generator's <code>n</code>, and <code>e</code> values. The
92
   * for this generator's <code>n</code>, and <code>e</code> values. The
95
   * default is to generate <code>n</code> and use a fixed value for
93
   * default is to generate <code>n</code> and use a fixed value for
96
   * <code>e</.code> (Fermat's F4 number).
94
   * <code>e</.code> (Fermat's F4 number).
97
   */
95
   */
Lines 128-154 Link Here
128
  /** Preferred encoding format of generated keys. */
126
  /** Preferred encoding format of generated keys. */
129
  private int preferredFormat;
127
  private int preferredFormat;
130
128
131
  // Constructor(s)
132
  // -------------------------------------------------------------------------
133
134
  // implicit 0-arguments constructor
129
  // implicit 0-arguments constructor
135
130
136
  // Class methods
137
  // -------------------------------------------------------------------------
138
139
  // gnu.crypto.key.IKeyPairGenerator interface implementation ---------------
140
141
  public String name()
131
  public String name()
142
  {
132
  {
143
    return Registry.RSA_KPG;
133
    return Registry.RSA_KPG;
144
  }
134
  }
145
135
146
  /**
136
  /**
147
   * <p>Configures this instance.</p>
137
   * Configures this instance.
148
   *
138
   * 
149
   * @param attributes the map of name/value pairs to use.
139
   * @param attributes the map of name/value pairs to use.
150
   * @exception IllegalArgumentException if the designated MODULUS_LENGTH
140
   * @exception IllegalArgumentException if the designated MODULUS_LENGTH value
151
   * value is less than 1024.
141
   *              is less than 1024.
152
   */
142
   */
153
  public void setup(Map attributes)
143
  public void setup(Map attributes)
154
  {
144
  {
Lines 156-165 Link Here
156
      log.entering(this.getClass().getName(), "setup", attributes);
146
      log.entering(this.getClass().getName(), "setup", attributes);
157
    // do we have a SecureRandom, or should we use our own?
147
    // do we have a SecureRandom, or should we use our own?
158
    rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
148
    rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
159
160
    // are we given a set of RSA params or we shall use our own?
149
    // are we given a set of RSA params or we shall use our own?
161
    RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) attributes.get(RSA_PARAMETERS);
150
    RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) attributes.get(RSA_PARAMETERS);
162
163
    // find out the modulus length
151
    // find out the modulus length
164
    if (params != null)
152
    if (params != null)
165
      {
153
      {
Lines 171-181 Link Here
171
        Integer l = (Integer) attributes.get(MODULUS_LENGTH);
159
        Integer l = (Integer) attributes.get(MODULUS_LENGTH);
172
        L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue());
160
        L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue());
173
      }
161
      }
174
175
    if (L < 1024)
162
    if (L < 1024)
176
      {
163
      throw new IllegalArgumentException(MODULUS_LENGTH);
177
        throw new IllegalArgumentException(MODULUS_LENGTH);
178
      }
179
164
180
    // what is the preferred encoding format
165
    // what is the preferred encoding format
181
    Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT);
166
    Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT);
Lines 186-203 Link Here
186
  }
171
  }
187
172
188
  /**
173
  /**
189
   * <p>The algorithm used here is described in <i>nessie-pss-B.pdf</i>
174
   * <p>
190
   * document which is part of the RSA-PSS submission to NESSIE.</p>
175
   * The algorithm used here is described in <i>nessie-pss-B.pdf</i> document
191
   *
176
   * which is part of the RSA-PSS submission to NESSIE.
177
   * </p>
178
   * 
192
   * @return an RSA keypair.
179
   * @return an RSA keypair.
193
   */
180
   */
194
  public KeyPair generate()
181
  public KeyPair generate()
195
  {
182
  {
196
    if (Configuration.DEBUG)
183
    if (Configuration.DEBUG)
197
      log.entering(this.getClass().getName(), "generate");
184
      log.entering(this.getClass().getName(), "generate");
198
199
    BigInteger p, q, n, d;
185
    BigInteger p, q, n, d;
200
201
    // 1. Generate a prime p in the interval [2**(M-1), 2**M - 1], where
186
    // 1. Generate a prime p in the interval [2**(M-1), 2**M - 1], where
202
    // M = CEILING(L/2), and such that GCD(p, e) = 1
187
    // M = CEILING(L/2), and such that GCD(p, e) = 1
203
    int M = (L + 1) / 2;
188
    int M = (L + 1) / 2;
Lines 210-220 Link Here
210
        p = new BigInteger(1, kb).setBit(0);
195
        p = new BigInteger(1, kb).setBit(0);
211
        if (p.compareTo(lower) >= 0 && p.compareTo(upper) <= 0
196
        if (p.compareTo(lower) >= 0 && p.compareTo(upper) <= 0
212
            && p.isProbablePrime(80) && p.gcd(e).equals(ONE))
197
            && p.isProbablePrime(80) && p.gcd(e).equals(ONE))
213
          {
198
          break step1;
214
            break step1;
215
          }
216
      }
199
      }
217
218
    // 2. Generate a prime q such that the product of p and q is an L-bit
200
    // 2. Generate a prime q such that the product of p and q is an L-bit
219
    // number, and such that GCD(q, e) = 1
201
    // number, and such that GCD(q, e) = 1
220
    step2: while (true)
202
    step2: while (true)
Lines 222-267 Link Here
222
        nextRandomBytes(kb);
204
        nextRandomBytes(kb);
223
        q = new BigInteger(1, kb).setBit(0);
205
        q = new BigInteger(1, kb).setBit(0);
224
        n = p.multiply(q);
206
        n = p.multiply(q);
225
        if (n.bitLength() == L && q.isProbablePrime(80)
207
        if (n.bitLength() == L && q.isProbablePrime(80) && q.gcd(e).equals(ONE))
226
            && q.gcd(e).equals(ONE))
208
          break step2;
227
          {
228
            break step2;
229
          }
230
231
        // TODO: test for p != q
209
        // TODO: test for p != q
232
      }
210
      }
233
234
    // TODO: ensure p < q
211
    // TODO: ensure p < q
235
236
    // 3. Put n = pq. The public key is (n, e).
212
    // 3. Put n = pq. The public key is (n, e).
237
    // 4. Compute the parameters necessary for the private key K (see
213
    // 4. Compute the parameters necessary for the private key K (see
238
    // Section 2.2).
214
    // Section 2.2).
239
    BigInteger phi = p.subtract(ONE).multiply(q.subtract(ONE));
215
    BigInteger phi = p.subtract(ONE).multiply(q.subtract(ONE));
240
    d = e.modInverse(phi);
216
    d = e.modInverse(phi);
241
242
    // 5. Output the public key and the private key.
217
    // 5. Output the public key and the private key.
243
    PublicKey pubK = new GnuRSAPublicKey(preferredFormat, n, e);
218
    PublicKey pubK = new GnuRSAPublicKey(preferredFormat, n, e);
244
    PrivateKey secK = new GnuRSAPrivateKey(preferredFormat, p, q, e, d);
219
    PrivateKey secK = new GnuRSAPrivateKey(preferredFormat, p, q, e, d);
245
246
    KeyPair result = new KeyPair(pubK, secK);
220
    KeyPair result = new KeyPair(pubK, secK);
247
    if (Configuration.DEBUG)
221
    if (Configuration.DEBUG)
248
      log.exiting(this.getClass().getName(), "generate", result);
222
      log.exiting(this.getClass().getName(), "generate", result);
249
    return result;
223
    return result;
250
  }
224
  }
251
225
252
  // helper methods ----------------------------------------------------------
253
254
  /**
226
  /**
255
   * <p>Fills the designated byte array with random data.</p>
227
   * Fills the designated byte array with random data.
256
   *
228
   * 
257
   * @param buffer the byte array to fill with random data.
229
   * @param buffer the byte array to fill with random data.
258
   */
230
   */
259
  private void nextRandomBytes(byte[] buffer)
231
  private void nextRandomBytes(byte[] buffer)
260
  {
232
  {
261
    if (rnd != null)
233
    if (rnd != null)
262
      {
234
      rnd.nextBytes(buffer);
263
        rnd.nextBytes(buffer);
264
      }
265
    else
235
    else
266
      getDefaultPRNG().nextBytes(buffer);
236
      getDefaultPRNG().nextBytes(buffer);
267
  }
237
  }
(-)rsa/RSAKeyPairPKCS8Codec.java (-10 / +5 lines)
Lines 85-91 Link Here
85
  /**
85
  /**
86
   * Returns the PKCS#8 ASN.1 <i>PrivateKeyInfo</i> representation of an RSA
86
   * Returns the PKCS#8 ASN.1 <i>PrivateKeyInfo</i> representation of an RSA
87
   * private key. The ASN.1 specification is as follows:
87
   * private key. The ASN.1 specification is as follows:
88
   * 
89
   * <pre>
88
   * <pre>
90
   *   PrivateKeyInfo ::= SEQUENCE {
89
   *   PrivateKeyInfo ::= SEQUENCE {
91
   *     version              INTEGER, -- MUST be 0
90
   *     version              INTEGER, -- MUST be 0
Lines 98-107 Link Here
98
   *     parameters  ANY DEFINED BY algorithm OPTIONAL
97
   *     parameters  ANY DEFINED BY algorithm OPTIONAL
99
   *   }
98
   *   }
100
   * </pre>
99
   * </pre>
101
   * 
100
   * <p>
102
   * <p>The <i>privateKey</i> field, which is an OCTET STRING, contains the
101
   * The <i>privateKey</i> field, which is an OCTET STRING, contains the
103
   * DER-encoded form of the RSA private key defined as:</p>
102
   * DER-encoded form of the RSA private key defined as:
104
   * 
105
   * <pre>
103
   * <pre>
106
   *   RSAPrivateKey ::= SEQUENCE {
104
   *   RSAPrivateKey ::= SEQUENCE {
107
   *     version                 INTEGER, -- MUST be 0
105
   *     version                 INTEGER, -- MUST be 0
Lines 125-131 Link Here
125
  {
123
  {
126
    if (Configuration.DEBUG)
124
    if (Configuration.DEBUG)
127
      log.entering(this.getClass().getName(), "encodePrivateKey()", key);
125
      log.entering(this.getClass().getName(), "encodePrivateKey()", key);
128
129
    if (! (key instanceof GnuRSAPrivateKey))
126
    if (! (key instanceof GnuRSAPrivateKey))
130
      throw new InvalidParameterException("Wrong key type");
127
      throw new InvalidParameterException("Wrong key type");
131
128
Lines 217-223 Link Here
217
  {
214
  {
218
    if (Configuration.DEBUG)
215
    if (Configuration.DEBUG)
219
      log.entering(this.getClass().getName(), "decodePrivateKey()", input);
216
      log.entering(this.getClass().getName(), "decodePrivateKey()", input);
220
221
    if (input == null)
217
    if (input == null)
222
      throw new InvalidParameterException("Input bytes MUST NOT be null");
218
      throw new InvalidParameterException("Input bytes MUST NOT be null");
223
219
Lines 287-295 Link Here
287
        y.initCause(x);
283
        y.initCause(x);
288
        throw y;
284
        throw y;
289
      }
285
      }
290
286
    PrivateKey result = new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
291
    PrivateKey result = new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, n, e,
287
                                             n, e, d, p, q, dP, dQ, qInv);
292
                                             d, p, q, dP, dQ, qInv);
293
    if (Configuration.DEBUG)
288
    if (Configuration.DEBUG)
294
      log.exiting(this.getClass().getName(), "decodePrivateKey()", result);
289
      log.exiting(this.getClass().getName(), "decodePrivateKey()", result);
295
    return result;
290
    return result;
(-)rsa/RSAKeyPairRawCodec.java (-120 / +90 lines)
Lines 47-126 Link Here
47
import java.security.PublicKey;
47
import java.security.PublicKey;
48
48
49
/**
49
/**
50
 * <p>An object that implements the {@link IKeyPairCodec} interface for the
50
 * An object that implements the {@link IKeyPairCodec} interface for the <i>Raw</i>
51
 * <i>Raw</i> format to use with RSA keypairs.</p>
51
 * format to use with RSA keypairs.
52
 *
52
 * 
53
 * @version $Revision: 1.1 $
53
 * @version $Revision: 1.1 $
54
 */
54
 */
55
public class RSAKeyPairRawCodec implements IKeyPairCodec
55
public class RSAKeyPairRawCodec
56
    implements IKeyPairCodec
56
{
57
{
57
58
  // Constants and variables
59
  // -------------------------------------------------------------------------
60
61
  // Constructor(s)
62
  // -------------------------------------------------------------------------
63
64
  // implicit 0-arguments constructor
58
  // implicit 0-arguments constructor
65
59
66
  // Class methods
67
  // -------------------------------------------------------------------------
68
69
  // Instance methods
70
  // -------------------------------------------------------------------------
71
72
  // gnu.crypto.key.IKeyPairCodec interface implementation -------------------
73
74
  public int getFormatID()
60
  public int getFormatID()
75
  {
61
  {
76
    return RAW_FORMAT;
62
    return RAW_FORMAT;
77
  }
63
  }
78
64
79
  /**
65
  /**
80
   * <p>Returns the encoded form of the designated RSA public key according to
66
   * Returns the encoded form of the designated RSA public key according to the
81
   * the <i>Raw</i> format supported by this library.</p>
67
   * <i>Raw</i> format supported by this library.
82
   *
68
   * <p>
83
   * <p>The <i>Raw</i> format for an RSA public key, in this implementation, is
69
   * The <i>Raw</i> format for an RSA public key, in this implementation, is a
84
   * a byte sequence consisting of the following:</p>
70
   * byte sequence consisting of the following:
85
   *
86
   * <ol>
71
   * <ol>
87
   *		<li>4-byte magic consisting of the value of the literal
72
   * <li>4-byte magic consisting of the value of the literal
88
   *    {@link Registry#MAGIC_RAW_RSA_PUBLIC_KEY},<li>
73
   * {@link Registry#MAGIC_RAW_RSA_PUBLIC_KEY},</li>
89
   *		<li>1-byte version consisting of the constant: 0x01,</li>
74
   * <li>1-byte version consisting of the constant: 0x01,</li>
90
   *		<li>4-byte count of following bytes representing the RSA parameter
75
   * <li>4-byte count of following bytes representing the RSA parameter
91
   *		<code>n</code> (the modulus) in internet order,</li>
76
   * <code>n</code> (the modulus) in internet order,</li>
92
   *		<li>n-bytes representation of a {@link BigInteger} obtained by invoking
77
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
93
   *    the <code>toByteArray()</code> method on the RSA parameter <code>n</code>,</li>
78
   * the <code>toByteArray()</code> method on the RSA parameter <code>n</code>,
94
   *		<li>4-byte count of following bytes representing the RSA parameter
79
   * </li>
95
   *		<code>e</code> (the public exponent) in internet order,</li>
80
   * <li>4-byte count of following bytes representing the RSA parameter
96
   *		<li>n-bytes representation of a {@link BigInteger} obtained by invoking
81
   * <code>e</code> (the public exponent) in internet order,</li>
97
   *    the <code>toByteArray()</code> method on the RSA parameter <code>e</code>.</li>
82
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
83
   * the <code>toByteArray()</code> method on the RSA parameter <code>e</code>.
84
   * </li>
98
   * </ol>
85
   * </ol>
99
   *
86
   * 
100
   * @param key the key to encode.
87
   * @param key the key to encode.
101
   * @return the <i>Raw</i> format encoding of the designated key.
88
   * @return the <i>Raw</i> format encoding of the designated key.
102
   * @exception IllegalArgumentException if the designated key is not an RSA
89
   * @exception IllegalArgumentException if the designated key is not an RSA
103
   * one.
90
   *              one.
104
   */
91
   */
105
  public byte[] encodePublicKey(PublicKey key)
92
  public byte[] encodePublicKey(PublicKey key)
106
  {
93
  {
107
    if (!(key instanceof GnuRSAPublicKey))
94
    if (! (key instanceof GnuRSAPublicKey))
108
      {
95
      throw new IllegalArgumentException("key");
109
        throw new IllegalArgumentException("key");
110
      }
111
96
112
    GnuRSAPublicKey rsaKey = (GnuRSAPublicKey) key;
97
    GnuRSAPublicKey rsaKey = (GnuRSAPublicKey) key;
113
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
98
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
114
115
    // magic
99
    // magic
116
    baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0]);
100
    baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0]);
117
    baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1]);
101
    baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1]);
118
    baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2]);
102
    baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2]);
119
    baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3]);
103
    baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3]);
120
121
    // version
104
    // version
122
    baos.write(0x01);
105
    baos.write(0x01);
123
124
    // n
106
    // n
125
    byte[] buffer = rsaKey.getModulus().toByteArray();
107
    byte[] buffer = rsaKey.getModulus().toByteArray();
126
    int length = buffer.length;
108
    int length = buffer.length;
Lines 129-135 Link Here
129
    baos.write((length >>> 8) & 0xFF);
111
    baos.write((length >>> 8) & 0xFF);
130
    baos.write(length & 0xFF);
112
    baos.write(length & 0xFF);
131
    baos.write(buffer, 0, length);
113
    baos.write(buffer, 0, length);
132
133
    // e
114
    // e
134
    buffer = rsaKey.getPublicExponent().toByteArray();
115
    buffer = rsaKey.getPublicExponent().toByteArray();
135
    length = buffer.length;
116
    length = buffer.length;
Lines 138-144 Link Here
138
    baos.write((length >>> 8) & 0xFF);
119
    baos.write((length >>> 8) & 0xFF);
139
    baos.write(length & 0xFF);
120
    baos.write(length & 0xFF);
140
    baos.write(buffer, 0, length);
121
    baos.write(buffer, 0, length);
141
142
    return baos.toByteArray();
122
    return baos.toByteArray();
143
  }
123
  }
144
124
Lines 149-240 Link Here
149
        || k[1] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1]
129
        || k[1] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1]
150
        || k[2] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2]
130
        || k[2] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2]
151
        || k[3] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3])
131
        || k[3] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3])
152
      {
132
      throw new IllegalArgumentException("magic");
153
        throw new IllegalArgumentException("magic");
154
      }
155
133
156
    // version
134
    // version
157
    if (k[4] != 0x01)
135
    if (k[4] != 0x01)
158
      {
136
      throw new IllegalArgumentException("version");
159
        throw new IllegalArgumentException("version");
160
      }
161
    int i = 5;
162
137
138
    int i = 5;
163
    int l;
139
    int l;
164
    byte[] buffer;
140
    byte[] buffer;
165
166
    // n
141
    // n
167
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
142
    l =  k[i++]         << 24
168
        | (k[i++] & 0xFF);
143
      | (k[i++] & 0xFF) << 16
144
      | (k[i++] & 0xFF) << 8
145
      | (k[i++] & 0xFF);
169
    buffer = new byte[l];
146
    buffer = new byte[l];
170
    System.arraycopy(k, i, buffer, 0, l);
147
    System.arraycopy(k, i, buffer, 0, l);
171
    i += l;
148
    i += l;
172
    BigInteger n = new BigInteger(1, buffer);
149
    BigInteger n = new BigInteger(1, buffer);
173
174
    // e
150
    // e
175
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
151
    l =  k[i++]         << 24
176
        | (k[i++] & 0xFF);
152
      | (k[i++] & 0xFF) << 16
153
      | (k[i++] & 0xFF) << 8
154
      | (k[i++] & 0xFF);
177
    buffer = new byte[l];
155
    buffer = new byte[l];
178
    System.arraycopy(k, i, buffer, 0, l);
156
    System.arraycopy(k, i, buffer, 0, l);
179
    i += l;
157
    i += l;
180
    BigInteger e = new BigInteger(1, buffer);
158
    BigInteger e = new BigInteger(1, buffer);
181
182
    return new GnuRSAPublicKey(n, e);
159
    return new GnuRSAPublicKey(n, e);
183
  }
160
  }
184
161
185
  /**
162
  /**
186
   * <p>Returns the encoded form of the designated RSA private key according to
163
   * Returns the encoded form of the designated RSA private key according to the
187
   * the <i>Raw</i> format supported by this library.</p>
164
   * <i>Raw</i> format supported by this library.
188
   *
165
   * <p>
189
   * <p>The <i>Raw</i> format for an RSA private key, in this implementation,
166
   * The <i>Raw</i> format for an RSA private key, in this implementation, is a
190
   * is a byte sequence consisting of the following:</p>
167
   * byte sequence consisting of the following:
191
   *
192
   * <ol>
168
   * <ol>
193
   *		<li>4-byte magic consisting of the value of the literal
169
   * <li>4-byte magic consisting of the value of the literal
194
   *    {@link Registry#MAGIC_RAW_RSA_PRIVATE_KEY},<li>
170
   * {@link Registry#MAGIC_RAW_RSA_PRIVATE_KEY},</li>
195
   *		<li>1-byte version consisting of the constant: 0x01,</li>
171
   * <li>1-byte version consisting of the constant: 0x01,</li>
196
   *		<li>4-byte count of following bytes representing the RSA parameter
172
   * <li>4-byte count of following bytes representing the RSA parameter
197
   *		<code>p</code> (the first prime factor of the modulus) in internet
173
   * <code>p</code> (the first prime factor of the modulus) in internet order,
198
   *    order,</li>
174
   * </li>
199
   *		<li>n-bytes representation of a {@link BigInteger} obtained by invoking
175
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
200
   *    the <code>toByteArray()</code> method on the RSA parameter <code>p</code>,</li>
176
   * the <code>toByteArray()</code> method on the RSA parameter <code>p</code>,
201
   *		<li>4-byte count of following bytes representing the RSA parameter
177
   * </li>
202
   *		<code>q</code> (the second prime factor of the modulus) in internet
178
   * <li>4-byte count of following bytes representing the RSA parameter
203
   *    order,</li>
179
   * <code>q</code> (the second prime factor of the modulus) in internet
204
   *		<li>n-bytes representation of a {@link BigInteger} obtained by invoking
180
   * order,</li>
205
   *    the <code>toByteArray()</code> method on the RSA parameter <code>q</code>,</li>
181
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
206
   *		<li>4-byte count of following bytes representing the RSA parameter
182
   * the <code>toByteArray()</code> method on the RSA parameter <code>q</code>,
207
   *		<code>e</code> (the public exponent) in internet order,</li>
183
   * </li>
208
   *		<li>n-bytes representation of a {@link BigInteger} obtained by invoking
184
   * <li>4-byte count of following bytes representing the RSA parameter
209
   *    the <code>toByteArray()</code> method on the RSA parameter <code>e</code>,</li>
185
   * <code>e</code> (the public exponent) in internet order,</li>
210
   *		<li>4-byte count of following bytes representing the RSA parameter
186
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
211
   *		<code>d</code> (the private exponent) in internet order,</li>
187
   * the <code>toByteArray()</code> method on the RSA parameter <code>e</code>,
212
   *		<li>n-bytes representation of a {@link BigInteger} obtained by invoking
188
   * </li>
213
   *    the <code>toByteArray()</code> method on the RSA parameter <code>d</code>,</li>
189
   * <li>4-byte count of following bytes representing the RSA parameter
190
   * <code>d</code> (the private exponent) in internet order,</li>
191
   * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
192
   * the <code>toByteArray()</code> method on the RSA parameter <code>d</code>,
193
   * </li>
214
   * </ol>
194
   * </ol>
215
   *
195
   * 
216
   * @param key the key to encode.
196
   * @param key the key to encode.
217
   * @return the <i>Raw</i> format encoding of the designated key.
197
   * @return the <i>Raw</i> format encoding of the designated key.
218
   */
198
   */
219
  public byte[] encodePrivateKey(PrivateKey key)
199
  public byte[] encodePrivateKey(PrivateKey key)
220
  {
200
  {
221
    if (!(key instanceof GnuRSAPrivateKey))
201
    if (! (key instanceof GnuRSAPrivateKey))
222
      {
202
      throw new IllegalArgumentException("key");
223
        throw new IllegalArgumentException("key");
224
      }
225
203
226
    GnuRSAPrivateKey rsaKey = (GnuRSAPrivateKey) key;
204
    GnuRSAPrivateKey rsaKey = (GnuRSAPrivateKey) key;
227
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
205
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
228
229
    // magic
206
    // magic
230
    baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0]);
207
    baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0]);
231
    baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1]);
208
    baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1]);
232
    baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2]);
209
    baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2]);
233
    baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3]);
210
    baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3]);
234
235
    // version
211
    // version
236
    baos.write(0x01);
212
    baos.write(0x01);
237
238
    // p
213
    // p
239
    byte[] buffer = rsaKey.getPrimeP().toByteArray();
214
    byte[] buffer = rsaKey.getPrimeP().toByteArray();
240
    int length = buffer.length;
215
    int length = buffer.length;
Lines 243-249 Link Here
243
    baos.write((length >>> 8) & 0xFF);
218
    baos.write((length >>> 8) & 0xFF);
244
    baos.write(length & 0xFF);
219
    baos.write(length & 0xFF);
245
    baos.write(buffer, 0, length);
220
    baos.write(buffer, 0, length);
246
247
    // q
221
    // q
248
    buffer = rsaKey.getPrimeQ().toByteArray();
222
    buffer = rsaKey.getPrimeQ().toByteArray();
249
    length = buffer.length;
223
    length = buffer.length;
Lines 252-258 Link Here
252
    baos.write((length >>> 8) & 0xFF);
226
    baos.write((length >>> 8) & 0xFF);
253
    baos.write(length & 0xFF);
227
    baos.write(length & 0xFF);
254
    baos.write(buffer, 0, length);
228
    baos.write(buffer, 0, length);
255
256
    // e
229
    // e
257
    buffer = rsaKey.getPublicExponent().toByteArray();
230
    buffer = rsaKey.getPublicExponent().toByteArray();
258
    length = buffer.length;
231
    length = buffer.length;
Lines 261-267 Link Here
261
    baos.write((length >>> 8) & 0xFF);
234
    baos.write((length >>> 8) & 0xFF);
262
    baos.write(length & 0xFF);
235
    baos.write(length & 0xFF);
263
    baos.write(buffer, 0, length);
236
    baos.write(buffer, 0, length);
264
265
    // d
237
    // d
266
    buffer = rsaKey.getPrivateExponent().toByteArray();
238
    buffer = rsaKey.getPrivateExponent().toByteArray();
267
    length = buffer.length;
239
    length = buffer.length;
Lines 270-276 Link Here
270
    baos.write((length >>> 8) & 0xFF);
242
    baos.write((length >>> 8) & 0xFF);
271
    baos.write(length & 0xFF);
243
    baos.write(length & 0xFF);
272
    baos.write(buffer, 0, length);
244
    baos.write(buffer, 0, length);
273
274
    return baos.toByteArray();
245
    return baos.toByteArray();
275
  }
246
  }
276
247
Lines 281-332 Link Here
281
        || k[1] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1]
252
        || k[1] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1]
282
        || k[2] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2]
253
        || k[2] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2]
283
        || k[3] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3])
254
        || k[3] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3])
284
      {
255
      throw new IllegalArgumentException("magic");
285
        throw new IllegalArgumentException("magic");
286
      }
287
256
288
    // version
257
    // version
289
    if (k[4] != 0x01)
258
    if (k[4] != 0x01)
290
      {
259
      throw new IllegalArgumentException("version");
291
        throw new IllegalArgumentException("version");
292
      }
293
    int i = 5;
294
260
261
    int i = 5;
295
    int l;
262
    int l;
296
    byte[] buffer;
263
    byte[] buffer;
297
298
    // p
264
    // p
299
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
265
    l =  k[i++]         << 24
300
        | (k[i++] & 0xFF);
266
      | (k[i++] & 0xFF) << 16
267
      | (k[i++] & 0xFF) << 8
268
      | (k[i++] & 0xFF);
301
    buffer = new byte[l];
269
    buffer = new byte[l];
302
    System.arraycopy(k, i, buffer, 0, l);
270
    System.arraycopy(k, i, buffer, 0, l);
303
    i += l;
271
    i += l;
304
    BigInteger p = new BigInteger(1, buffer);
272
    BigInteger p = new BigInteger(1, buffer);
305
306
    // q
273
    // q
307
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
274
    l =  k[i++]         << 24
308
        | (k[i++] & 0xFF);
275
      | (k[i++] & 0xFF) << 16
276
      | (k[i++] & 0xFF) << 8
277
      | (k[i++] & 0xFF);
309
    buffer = new byte[l];
278
    buffer = new byte[l];
310
    System.arraycopy(k, i, buffer, 0, l);
279
    System.arraycopy(k, i, buffer, 0, l);
311
    i += l;
280
    i += l;
312
    BigInteger q = new BigInteger(1, buffer);
281
    BigInteger q = new BigInteger(1, buffer);
313
314
    // e
282
    // e
315
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
283
    l =  k[i++]         << 24
316
        | (k[i++] & 0xFF);
284
      | (k[i++] & 0xFF) << 16
285
      | (k[i++] & 0xFF) << 8
286
      | (k[i++] & 0xFF);
317
    buffer = new byte[l];
287
    buffer = new byte[l];
318
    System.arraycopy(k, i, buffer, 0, l);
288
    System.arraycopy(k, i, buffer, 0, l);
319
    i += l;
289
    i += l;
320
    BigInteger e = new BigInteger(1, buffer);
290
    BigInteger e = new BigInteger(1, buffer);
321
322
    // d
291
    // d
323
    l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
292
    l =  k[i++]         << 24
324
        | (k[i++] & 0xFF);
293
      | (k[i++] & 0xFF) << 16
294
      | (k[i++] & 0xFF) << 8
295
      | (k[i++] & 0xFF);
325
    buffer = new byte[l];
296
    buffer = new byte[l];
326
    System.arraycopy(k, i, buffer, 0, l);
297
    System.arraycopy(k, i, buffer, 0, l);
327
    i += l;
298
    i += l;
328
    BigInteger d = new BigInteger(1, buffer);
299
    BigInteger d = new BigInteger(1, buffer);
329
330
    return new GnuRSAPrivateKey(p, q, e, d);
300
    return new GnuRSAPrivateKey(p, q, e, d);
331
  }
301
  }
332
}
302
}
(-)rsa/RSAKeyPairX509Codec.java (-5 / +2 lines)
Lines 117-123 Link Here
117
  {
117
  {
118
    if (Configuration.DEBUG)
118
    if (Configuration.DEBUG)
119
      log.entering(this.getClass().getName(), "encodePublicKey()", key);
119
      log.entering(this.getClass().getName(), "encodePublicKey()", key);
120
121
    if (! (key instanceof GnuRSAPublicKey))
120
    if (! (key instanceof GnuRSAPublicKey))
122
      throw new InvalidParameterException("key");
121
      throw new InvalidParameterException("key");
123
122
Lines 158-164 Link Here
158
      }
157
      }
159
    catch (IOException x)
158
    catch (IOException x)
160
      {
159
      {
161
        InvalidParameterException y = new InvalidParameterException();
160
        InvalidParameterException y = new InvalidParameterException(x.getMessage());
162
        y.initCause(x);
161
        y.initCause(x);
163
        throw y;
162
        throw y;
164
      }
163
      }
Lines 187-193 Link Here
187
  {
186
  {
188
    if (Configuration.DEBUG)
187
    if (Configuration.DEBUG)
189
      log.entering(this.getClass().getName(), "decodePublicKey()", input);
188
      log.entering(this.getClass().getName(), "decodePublicKey()", input);
190
191
    if (input == null)
189
    if (input == null)
192
      throw new InvalidParameterException("Input bytes MUST NOT be null");
190
      throw new InvalidParameterException("Input bytes MUST NOT be null");
193
191
Lines 232-242 Link Here
232
      }
230
      }
233
    catch (IOException x)
231
    catch (IOException x)
234
      {
232
      {
235
        InvalidParameterException y = new InvalidParameterException();
233
        InvalidParameterException y = new InvalidParameterException(x.getMessage());
236
        y.initCause(x);
234
        y.initCause(x);
237
        throw y;
235
        throw y;
238
      }
236
      }
239
240
    PublicKey result = new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
237
    PublicKey result = new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
241
    if (Configuration.DEBUG)
238
    if (Configuration.DEBUG)
242
      log.exiting(this.getClass().getName(), "decodePublicKey()", result);
239
      log.exiting(this.getClass().getName(), "decodePublicKey()", result);

Return to bug 26067