001/*
002 * Copyright 2017-2020 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2017-2020 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2017-2020 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.util.ssl.cert;
037
038
039
040import java.math.BigInteger;
041import java.util.ArrayList;
042import java.util.Collections;
043import java.util.Iterator;
044import java.util.List;
045
046import com.unboundid.asn1.ASN1BigInteger;
047import com.unboundid.asn1.ASN1Element;
048import com.unboundid.asn1.ASN1Integer;
049import com.unboundid.asn1.ASN1OctetString;
050import com.unboundid.asn1.ASN1Sequence;
051import com.unboundid.util.Debug;
052import com.unboundid.util.NotMutable;
053import com.unboundid.util.StaticUtils;
054import com.unboundid.util.ThreadSafety;
055import com.unboundid.util.ThreadSafetyLevel;
056
057import static com.unboundid.util.ssl.cert.CertMessages.*;
058
059
060
061/**
062 * This class provides a data structure for representing the information
063 * contained in an RSA private key.  As per
064 * <A HREF="https://www.ietf.org/rfc/rfc8017.txt">RFC 8017</A> section A.1.2,
065 * an RSA private key is identified by OID 1.2.840.113549.1.1.1 and the value is
066 * encoded as follows:
067 * <PRE>
068 *   RSAPrivateKey ::= SEQUENCE {
069 *       version           Version,
070 *       modulus           INTEGER,  -- n
071 *       publicExponent    INTEGER,  -- e
072 *       privateExponent   INTEGER,  -- d
073 *       prime1            INTEGER,  -- p
074 *       prime2            INTEGER,  -- q
075 *       exponent1         INTEGER,  -- d mod (p-1)
076 *       exponent2         INTEGER,  -- d mod (q-1)
077 *       coefficient       INTEGER,  -- (inverse of q) mod p
078 *       otherPrimeInfos   OtherPrimeInfos OPTIONAL
079 *   }
080 *
081 *   OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
082 *
083 *   OtherPrimeInfo ::= SEQUENCE {
084 *       prime             INTEGER,  -- ri
085 *       exponent          INTEGER,  -- di
086 *       coefficient       INTEGER   -- ti
087 *   }
088 * </PRE>
089 */
090@NotMutable()
091@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
092public final class RSAPrivateKey
093       extends DecodedPrivateKey
094{
095  /**
096   * The serial version UID for this serializable class.
097   */
098  private static final long serialVersionUID = -7101141316095373904L;
099
100
101
102  // The coefficient value for the RSA private key.
103  private final BigInteger coefficient;
104
105  // The exponent1 value for the RSA private key.
106  private final BigInteger exponent1;
107
108  // The exponent2 value for the RSA private key.
109  private final BigInteger exponent2;
110
111  // The modulus for the RSA private key.
112  private final BigInteger modulus;
113
114  // The prime1 value for the RSA private key.
115  private final BigInteger prime1;
116
117  // The prime2 value for the RSA private key.
118  private final BigInteger prime2;
119
120  // The private exponent for the RSA private key.
121  private final BigInteger privateExponent;
122
123  // The public exponent for the RSA private key.
124  private final BigInteger publicExponent;
125
126  // A list of information about additional primes used by the RSA private key.
127  private final List<BigInteger[]> otherPrimeInfos;
128
129  // The private key version.
130  private final RSAPrivateKeyVersion version;
131
132
133
134  /**
135   * Creates a new RSA private key with the provided information.
136   *
137   * @param  version          The version for this private key.  It must not be
138   *                          {@code null}.
139   * @param  modulus          The modulus for this RSA private key.  It must not
140   *                          be {@code null}.
141   * @param  publicExponent   The public exponent for this RSA private key.  It
142   *                          must not be {@code null}.
143   * @param  privateExponent  The private exponent for this RSA private key.  It
144   *                          must not be {@code null}.
145   * @param  prime1           The prime1 value for this RSA private key.  It
146   *                          must not be {@code null}.
147   * @param  prime2           The prime2 value for this RSA private key.  It
148   *                          must not be {@code null}.
149   * @param  exponent1        The exponent1 value for this RSA private key.  It
150   *                          must not be {@code null}.
151   * @param  exponent2        The exponent2 value for this RSA private key.  It
152   *                          must not be {@code null}.
153   * @param  coefficient      The coefficient for this RSA private key. It must
154   *                          not be {@code null}.
155   * @param  otherPrimeInfos  A list of information about additional primes used
156   *                          by the private key.  It must not be {@code null},
157   *                          but may be empty.  If it is non-empty, then each
158   *                          array must contain three items, which represent a
159   *                          prime, an exponent, and a coefficient,
160   *                          respectively.
161   */
162  RSAPrivateKey(final RSAPrivateKeyVersion version, final BigInteger modulus,
163                final BigInteger publicExponent,
164                final BigInteger privateExponent, final BigInteger prime1,
165                final BigInteger prime2, final BigInteger exponent1,
166                final BigInteger exponent2, final BigInteger coefficient,
167                final List<BigInteger[]> otherPrimeInfos)
168  {
169    this.version = version;
170    this.modulus = modulus;
171    this.publicExponent = publicExponent;
172    this.privateExponent = privateExponent;
173    this.prime1 = prime1;
174    this.prime2 = prime2;
175    this.exponent1 = exponent1;
176    this.exponent2 = exponent2;
177    this.coefficient = coefficient;
178    this.otherPrimeInfos = otherPrimeInfos;
179  }
180
181
182
183  /**
184   * Creates a new RSA decoded private key from the provided octet string.
185   *
186   * @param  encodedPrivateKey  The encoded private key to be decoded as an RSA
187   *                            private key.
188   *
189   * @throws  CertException  If the provided private key cannot be decoded as an
190   *                         RSA private key.
191   */
192  RSAPrivateKey(final ASN1OctetString encodedPrivateKey)
193       throws CertException
194  {
195    try
196    {
197      final ASN1Element[] elements = ASN1Sequence.decodeAsSequence(
198           encodedPrivateKey.getValue()).elements();
199      final int versionIntValue = elements[0].decodeAsInteger().intValue();
200      version = RSAPrivateKeyVersion.valueOf(versionIntValue);
201      if (version == null)
202      {
203        throw new CertException(
204             ERR_RSA_PRIVATE_KEY_UNSUPPORTED_VERSION.get(versionIntValue));
205      }
206
207      modulus = elements[1].decodeAsBigInteger().getBigIntegerValue();
208      publicExponent = elements[2].decodeAsBigInteger().getBigIntegerValue();
209      privateExponent = elements[3].decodeAsBigInteger().getBigIntegerValue();
210      prime1 = elements[4].decodeAsBigInteger().getBigIntegerValue();
211      prime2 = elements[5].decodeAsBigInteger().getBigIntegerValue();
212      exponent1 = elements[6].decodeAsBigInteger().getBigIntegerValue();
213      exponent2 = elements[7].decodeAsBigInteger().getBigIntegerValue();
214      coefficient = elements[8].decodeAsBigInteger().getBigIntegerValue();
215
216      if (elements.length == 9)
217      {
218        otherPrimeInfos = Collections.emptyList();
219      }
220      else
221      {
222        final ASN1Element[] otherPrimesElements =
223             elements[9].decodeAsSequence().elements();
224        final ArrayList<BigInteger[]> otherPrimes =
225             new ArrayList<>(otherPrimesElements.length);
226        for (final ASN1Element e : otherPrimesElements)
227        {
228          final ASN1Element[] primeElements = e.decodeAsSequence().elements();
229          otherPrimes.add(
230               new BigInteger[]
231               {
232                 primeElements[0].decodeAsBigInteger().getBigIntegerValue(),
233                 primeElements[1].decodeAsBigInteger().getBigIntegerValue(),
234                 primeElements[2].decodeAsBigInteger().getBigIntegerValue()
235               });
236        }
237
238        otherPrimeInfos = Collections.unmodifiableList(otherPrimes);
239      }
240    }
241    catch (final CertException e)
242    {
243      Debug.debugException(e);
244      throw e;
245    }
246    catch (final Exception e)
247    {
248      Debug.debugException(e);
249      throw new CertException(
250           ERR_RSA_PRIVATE_KEY_CANNOT_DECODE.get(
251                StaticUtils.getExceptionMessage(e)),
252           e);
253    }
254  }
255
256
257
258  /**
259   * Encodes this RSA private key to an ASN.1 octet string.
260   *
261   * @return  The ASN.1 octet string containing the encoded private key.
262   */
263  ASN1OctetString encode()
264  {
265    final ArrayList<ASN1Element> elements = new ArrayList<>(9);
266    elements.add(new ASN1Integer(version.getIntValue()));
267    elements.add(new ASN1BigInteger(modulus));
268    elements.add(new ASN1BigInteger(publicExponent));
269    elements.add(new ASN1BigInteger(privateExponent));
270    elements.add(new ASN1BigInteger(prime1));
271    elements.add(new ASN1BigInteger(prime2));
272    elements.add(new ASN1BigInteger(exponent1));
273    elements.add(new ASN1BigInteger(exponent2));
274    elements.add(new ASN1BigInteger(coefficient));
275
276    if (! otherPrimeInfos.isEmpty())
277    {
278      final ArrayList<ASN1Element> otherElements =
279           new ArrayList<>(otherPrimeInfos.size());
280      for (final BigInteger[] info : otherPrimeInfos)
281      {
282        otherElements.add(new ASN1Sequence(
283             new ASN1BigInteger(info[0]),
284             new ASN1BigInteger(info[1]),
285             new ASN1BigInteger(info[2])));
286      }
287
288      elements.add(new ASN1Sequence(otherElements));
289    }
290
291    return new ASN1OctetString(new ASN1Sequence(elements).encode());
292  }
293
294
295
296  /**
297   * Retrieves the version for the RSA private key.
298   *
299   * @return  The version for the RSA private key.
300   */
301  public RSAPrivateKeyVersion getVersion()
302  {
303    return version;
304  }
305
306
307
308  /**
309   * Retrieves the modulus (n) for the RSA private key.
310   *
311   * @return  The modulus for the RSA private key.
312   */
313  public BigInteger getModulus()
314  {
315    return modulus;
316  }
317
318
319
320  /**
321   * Retrieves the public exponent (e) for the RSA public key.
322   *
323   * @return  The public exponent for the RSA public key.
324   */
325  public BigInteger getPublicExponent()
326  {
327    return publicExponent;
328  }
329
330
331
332  /**
333   * Retrieves the private exponent (d) for the RSA private key.
334   *
335   * @return  The private exponent for the RSA private key.
336   */
337  public BigInteger getPrivateExponent()
338  {
339    return privateExponent;
340  }
341
342
343
344  /**
345   * Retrieves the prime1 (p) value for the RSA private key.
346   *
347   * @return  The prime1 value for the RSA private key.
348   */
349  public BigInteger getPrime1()
350  {
351    return prime1;
352  }
353
354
355
356  /**
357   * Retrieves the prime2 (q) value for the RSA private key.
358   *
359   * @return  The prime2 value for the RSA private key.
360   */
361  public BigInteger getPrime2()
362  {
363    return prime2;
364  }
365
366
367
368  /**
369   * Retrieves the exponent1 value for the RSA private key.
370   *
371   * @return  The exponent1 value for the RSA private key.
372   */
373  public BigInteger getExponent1()
374  {
375    return exponent1;
376  }
377
378
379
380  /**
381   * Retrieves the exponent2 value for the RSA private key.
382   *
383   * @return  The exponent2 value for the RSA private key.
384   */
385  public BigInteger getExponent2()
386  {
387    return exponent2;
388  }
389
390
391
392  /**
393   * Retrieves the coefficient for the RSA private key.
394   *
395   * @return  The coefficient for the RSA private key.
396   */
397  public BigInteger getCoefficient()
398  {
399    return coefficient;
400  }
401
402
403
404  /**
405   * Retrieves a list of information about other primes used by the private key.
406   * If the list is non-empty, then each item will be an array of three
407   * {@code BigInteger} values, which represent a prime, an exponent, and a
408   * coefficient, respectively.
409   *
410   * @return  A list of information about other primes used by the private key.
411   */
412  public List<BigInteger[]> getOtherPrimeInfos()
413  {
414    return otherPrimeInfos;
415  }
416
417
418
419  /**
420   * {@inheritDoc}
421   */
422  @Override()
423  public void toString(final StringBuilder buffer)
424  {
425    buffer.append("RSAPrivateKey(version='");
426    buffer.append(version.getName());
427    buffer.append("', modulus=");
428    StaticUtils.toHex(modulus.toByteArray(), ":", buffer);
429    buffer.append(", publicExponent=");
430    StaticUtils.toHex(publicExponent.toByteArray(), ":", buffer);
431    buffer.append(", privateExponent=");
432    StaticUtils.toHex(privateExponent.toByteArray(), ":", buffer);
433    buffer.append(", prime1=");
434    StaticUtils.toHex(prime1.toByteArray(), ":", buffer);
435    buffer.append(", prime2=");
436    StaticUtils.toHex(prime2.toByteArray(), ":", buffer);
437    buffer.append(", exponent1=");
438    StaticUtils.toHex(exponent1.toByteArray(), ":", buffer);
439    buffer.append(", exponent2=");
440    StaticUtils.toHex(exponent2.toByteArray(), ":", buffer);
441    buffer.append(", coefficient=");
442    StaticUtils.toHex(coefficient.toByteArray(), ":", buffer);
443
444    if (! otherPrimeInfos.isEmpty())
445    {
446      buffer.append(", otherPrimeInfos={");
447
448      final Iterator<BigInteger[]> iterator = otherPrimeInfos.iterator();
449      while (iterator.hasNext())
450      {
451        final BigInteger[] array = iterator.next();
452        buffer.append("PrimeInfo(prime=");
453        StaticUtils.toHex(array[0].toByteArray(), ":", buffer);
454        buffer.append(", exponent=");
455        StaticUtils.toHex(array[1].toByteArray(), ":", buffer);
456        buffer.append(", coefficient=");
457        StaticUtils.toHex(array[2].toByteArray(), ":", buffer);
458        buffer.append(')');
459
460        if (iterator.hasNext())
461        {
462          buffer.append(", ");
463        }
464      }
465
466      buffer.append('}');
467    }
468
469    buffer.append(')');
470  }
471}