001/*
002 * Copyright 2022-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2022-2024 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) 2022-2024 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.ldap.sdk.unboundidds.logs.v2.json;
037
038
039
040import java.io.Serializable;
041import java.util.Date;
042
043import com.unboundid.ldap.sdk.unboundidds.logs.v2.LogField;
044import com.unboundid.util.Debug;
045import com.unboundid.util.NotMutable;
046import com.unboundid.util.NotNull;
047import com.unboundid.util.Nullable;
048import com.unboundid.util.StaticUtils;
049import com.unboundid.util.ThreadSafety;
050import com.unboundid.util.ThreadSafetyLevel;
051import com.unboundid.util.json.JSONObject;
052
053
054
055/**
056 * This class provides a data structure that contains information about a
057 * JSON-formatted certificate.
058 * <BR>
059 * <BLOCKQUOTE>
060 *   <B>NOTE:</B>  This class, and other classes within the
061 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
062 *   supported for use against Ping Identity, UnboundID, and
063 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
064 *   for proprietary functionality or for external specifications that are not
065 *   considered stable or mature enough to be guaranteed to work in an
066 *   interoperable way with other types of LDAP servers.
067 * </BLOCKQUOTE>
068 */
069@NotMutable()
070@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
071public final class JSONCertificate
072       implements Serializable
073{
074  /**
075   * The serial version UID for this serializable class.
076   */
077  private static final long serialVersionUID = -765694943228378726L;
078
079
080
081  // The JSON object with an encoded representation of this certificate.
082  @NotNull private final JSONObject certificateObject;
083
084  // The ntoAfter time for this certificate.
085  @Nullable private final Long notAfterTime;
086
087  // The notBefore time for this certificate.
088  @Nullable private final Long notBeforeTime;
089
090  // The certificate type for this certificate.
091  @Nullable private final String certificateType;
092
093  // The issuer subject DN for this certificate.
094  @Nullable private final String issuerSubjectDN;
095
096  // The serial number for this certificate.
097  @Nullable private final String serialNumber;
098
099  // The signature algorithm for this certificate.
100  @Nullable private final String signatureAlgorithm;
101
102  // The subject DN for this certificate.
103  @Nullable private final String subjectDN;
104
105
106
107  /**
108   * Creates a new JSON certificate that is decoded from the provided JSON
109   * object.
110   *
111   * @param  certificateObject  The JSON object containing an encoded
112   *                            representation of this certificate.
113   */
114  public JSONCertificate(@NotNull final JSONObject certificateObject)
115  {
116    this.certificateObject = certificateObject;
117
118    subjectDN = certificateObject.getFieldAsString(
119         JSONFormattedAccessLogFields.PEER_CERTIFICATE_CHAIN_SUBJECT_DN.
120              getFieldName());
121    issuerSubjectDN = certificateObject.getFieldAsString(
122         JSONFormattedAccessLogFields.PEER_CERTIFICATE_CHAIN_ISSUER_SUBJECT_DN.
123              getFieldName());
124    certificateType = certificateObject.getFieldAsString(
125         JSONFormattedAccessLogFields.PEER_CERTIFICATE_CHAIN_CERTIFICATE_TYPE.
126              getFieldName());
127    notBeforeTime = decodeTime(certificateObject,
128         JSONFormattedAccessLogFields.PEER_CERTIFICATE_CHAIN_NOT_BEFORE);
129    notAfterTime = decodeTime(certificateObject,
130         JSONFormattedAccessLogFields.PEER_CERTIFICATE_CHAIN_NOT_AFTER);
131    serialNumber = certificateObject.getFieldAsString(
132         JSONFormattedAccessLogFields.PEER_CERTIFICATE_CHAIN_SERIAL_NUMBER.
133              getFieldName());
134    signatureAlgorithm = certificateObject.getFieldAsString(
135         JSONFormattedAccessLogFields.
136              PEER_CERTIFICATE_CHAIN_SIGNATURE_ALGORITHM.getFieldName());
137  }
138
139
140
141  /**
142   * Decodes the time contained in the specified field of the given JSON object.
143   *
144   * @param  certificateObject  The JSON object containing an encoded
145   *                            representation of this certificate.  It must not
146   *                            be {@code null}.
147   * @param  logField           The field containing the time value to decode.
148   *                            It must not be {@code null}.
149   *
150   * @return  The decoded time, or {@code null} if the object did not contain
151   *          the specified field or if its value could not be parsed as a
152   *          timestamp in the ISO 8601 format described in RFC 3339.
153   */
154  @Nullable()
155  private static Long decodeTime(@NotNull final JSONObject certificateObject,
156                                 @NotNull final LogField logField)
157  {
158    final String timeString =
159         certificateObject.getFieldAsString(logField.getFieldName());
160    if (timeString == null)
161    {
162      return null;
163    }
164
165    try
166    {
167      return StaticUtils.decodeRFC3339Time(timeString).getTime();
168    }
169    catch (final Exception e)
170    {
171      Debug.debugException(e);
172      return null;
173    }
174  }
175
176
177
178  /**
179   * Retrieves the JSON object containing an encoded representation of this
180   * certificate.
181   *
182   * @return  The JSON object containing an encoded representation of this
183   *          certificate.
184   */
185  @NotNull()
186  public JSONObject getCertificateObject()
187  {
188    return certificateObject;
189  }
190
191
192
193  /**
194   * Retrieves a string representation of the subject DN for this certificate.
195   *
196   * @return  A string representation of the subject DN for this certificate, or
197   *          {@code null} if it is not included in the certificate object.
198   */
199  @Nullable()
200  public String getSubjectDN()
201  {
202    return subjectDN;
203  }
204
205
206
207  /**
208   * Retrieves a string representation of the subject DN of the issuer for this
209   * certificate.
210   *
211   * @return  A string representation of the subject DN of the issuer for this
212   *          certificate, or {@code null} if it is not included in the
213   *          certificate object.
214   */
215  @Nullable()
216  public String getIssuerSubjectDN()
217  {
218    return issuerSubjectDN;
219  }
220
221
222
223  /**
224   * Retrieves the certificate type for this certificate.
225   *
226   * @return  The certificate type for this certificate, or {@code null} if it
227   *          is not included in the certificate object.
228   */
229  @Nullable()
230  public String getCertificateType()
231  {
232    return certificateType;
233  }
234
235
236
237  /**
238   * Retrieves the notBefore time for this certificate.
239   *
240   * @return  The notBefore time for this certificate, or {@code null} if it is
241   *          not included in the certificate object or if its value cannot be
242   *          parsed.
243   */
244  @Nullable()
245  public Date getNotBeforeTime()
246  {
247    if (notBeforeTime == null)
248    {
249      return null;
250    }
251    else
252    {
253      return new Date(notBeforeTime);
254    }
255  }
256
257
258
259  /**
260   * Retrieves the notAfter time for this certificate.
261   *
262   * @return  The notAfter time for this certificate, or {@code null} if it is
263   *          not included in the certificate object or if its value cannot be
264   *          parsed.
265   */
266  @Nullable()
267  public Date getNotAfterTime()
268  {
269    if (notAfterTime == null)
270    {
271      return null;
272    }
273    else
274    {
275      return new Date(notAfterTime);
276    }
277  }
278
279
280
281  /**
282   * Retrieves a string representation of the serial number for this
283   * certificate.
284   *
285   * @return  A string representation of the serial number for this certificate,
286   *          or {@code null} if it is not included in the certificate object.
287   */
288  @Nullable()
289  public String getSerialNumber()
290  {
291    return serialNumber;
292  }
293
294
295
296  /**
297   * Retrieves the signature algorithm for this certificate.
298   *
299   * @return  The signature algorithm for this certificate, or {@code null} if
300   *          it is not included in the certificate object.
301   */
302  @Nullable()
303  public String getSignatureAlgorithm()
304  {
305    return signatureAlgorithm;
306  }
307
308
309
310  /**
311   * Retrieves a string representation of this JSON certificate.
312   *
313   * @return  A string representation of this JSON certificate.
314   */
315  @Override()
316  @NotNull()
317  public String toString()
318  {
319    return certificateObject.toSingleLineString();
320  }
321}