001/* 002 * Copyright 2017-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2017-2019 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.util.ssl.cert; 022 023 024 025import java.math.BigInteger; 026 027import com.unboundid.asn1.ASN1BigInteger; 028import com.unboundid.asn1.ASN1BitString; 029import com.unboundid.asn1.ASN1Element; 030import com.unboundid.asn1.ASN1Sequence; 031import com.unboundid.util.Debug; 032import com.unboundid.util.NotMutable; 033import com.unboundid.util.StaticUtils; 034import com.unboundid.util.ThreadSafety; 035import com.unboundid.util.ThreadSafetyLevel; 036 037import static com.unboundid.util.ssl.cert.CertMessages.*; 038 039 040 041/** 042 * This class provides a data structure for representing the information 043 * contained in an RSA public key in an X.509 certificate. As per 044 * <A HREF="https://www.ietf.org/rfc/rfc8017.txt">RFC 8017</A> section A.1.1, 045 * an RSA public key is identified by OID 1.2.840.113549.1.1.1 and the value is 046 * encoded as follows: 047 * <PRE> 048 * RSAPublicKey ::= SEQUENCE { 049 * modulus INTEGER, -- n 050 * publicExponent INTEGER } -- e 051 * </PRE> 052 */ 053@NotMutable() 054@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 055public final class RSAPublicKey 056 extends DecodedPublicKey 057{ 058 /** 059 * The serial version UID for this serializable class. 060 */ 061 private static final long serialVersionUID = 1837190736740174338L; 062 063 064 065 // The modulus for the RSA public key. 066 private final BigInteger modulus; 067 068 // The public exponent for the RSA public key. 069 private final BigInteger publicExponent; 070 071 072 073 /** 074 * Creates a new RSA public key with the provided information. 075 * 076 * @param modulus The modulus for this RSA public key. It must not 077 * be {@code null}. 078 * @param publicExponent The public exponent for this RSA public key. It 079 * must not be {@code null}. 080 */ 081 RSAPublicKey(final BigInteger modulus, final BigInteger publicExponent) 082 { 083 this.modulus = modulus; 084 this.publicExponent = publicExponent; 085 } 086 087 088 089 /** 090 * Creates a new RSA decoded public key from the provided bit string. 091 * 092 * @param subjectPublicKey The bit string containing the encoded public key. 093 * 094 * @throws CertException If the provided public key cannot be decoded as an 095 * RSA public key. 096 */ 097 RSAPublicKey(final ASN1BitString subjectPublicKey) 098 throws CertException 099 { 100 try 101 { 102 final byte[] keyBytes = subjectPublicKey.getBytes(); 103 final ASN1Element[] keyElements = 104 ASN1Sequence.decodeAsSequence(keyBytes).elements(); 105 modulus = keyElements[0].decodeAsBigInteger().getBigIntegerValue(); 106 publicExponent = keyElements[1].decodeAsBigInteger().getBigIntegerValue(); 107 } 108 catch (final Exception e) 109 { 110 Debug.debugException(e); 111 throw new CertException( 112 ERR_RSA_PUBLIC_KEY_CANNOT_DECODE.get( 113 StaticUtils.getExceptionMessage(e)), 114 e); 115 } 116 } 117 118 119 120 /** 121 * Encodes this RSA public key. 122 * 123 * @return The encoded representation of this RSA public key. 124 */ 125 ASN1BitString encode() 126 { 127 final ASN1Sequence publicKeySequence = new ASN1Sequence( 128 new ASN1BigInteger(modulus), 129 new ASN1BigInteger(publicExponent)); 130 final boolean[] bits = 131 ASN1BitString.getBitsForBytes(publicKeySequence.encode()); 132 return new ASN1BitString(bits); 133 } 134 135 136 137 /** 138 * Retrieves the modulus (n) for the RSA public key. 139 * 140 * @return The modulus for the RSA public key. 141 */ 142 public BigInteger getModulus() 143 { 144 return modulus; 145 } 146 147 148 149 /** 150 * Retrieves the public exponent (e) for the RSA public key. 151 * 152 * @return The public exponent for the RSA public key. 153 */ 154 public BigInteger getPublicExponent() 155 { 156 return publicExponent; 157 } 158 159 160 161 /** 162 * {@inheritDoc} 163 */ 164 @Override() 165 public void toString(final StringBuilder buffer) 166 { 167 buffer.append("RSAPublicKey(modulus="); 168 StaticUtils.toHex(modulus.toByteArray(), ":", buffer); 169 buffer.append(", publicExponent="); 170 StaticUtils.toHex(publicExponent.toByteArray(), ":", buffer); 171 buffer.append(')'); 172 } 173}