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.monitors;
037
038
039
040import java.util.Collections;
041import java.util.Date;
042import java.util.LinkedHashMap;
043import java.util.List;
044import java.util.Map;
045
046import com.unboundid.ldap.sdk.Entry;
047import com.unboundid.util.NotMutable;
048import com.unboundid.util.NotNull;
049import com.unboundid.util.Nullable;
050import com.unboundid.util.ThreadSafety;
051import com.unboundid.util.ThreadSafetyLevel;
052
053import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
054
055
056
057/**
058 * This class defines a monitor entry that provides information about X.509
059 * certificates that are in use by the Directory Server.
060 * <BR>
061 * <BLOCKQUOTE>
062 *   <B>NOTE:</B>  This class, and other classes within the
063 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
064 *   supported for use against Ping Identity, UnboundID, and
065 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
066 *   for proprietary functionality or for external specifications that are not
067 *   considered stable or mature enough to be guaranteed to work in an
068 *   interoperable way with other types of LDAP servers.
069 * </BLOCKQUOTE>
070 * <BR>
071 * The set of certificate monitor entries published by the directory server can
072 * be obtained using the {@link MonitorManager#getX509CertificateMonitorEntries}
073 * method.  Specific methods are available for accessing the associated monitor
074 * data (e.g., {@link #getSubjectDN} to retrieve the certificate's subject DN),
075 * and there are also methods for accessing this information in a generic manner
076 * (e.g., {@link #getMonitorAttributes} to retrieve all of the monitor
077 * attributes).  See the {@link MonitorManager} class documentation for an
078 * example that demonstrates the use of the generic API for accessing monitor
079 * data.
080 */
081@NotMutable()
082@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
083public final class X509CertificateMonitorEntry
084       extends MonitorEntry
085{
086  /**
087   * The structural object class used in X.509 certificate monitor entries.
088   */
089  @NotNull static final String X509_CERTIFICATE_MONITOR_OC =
090       "ds-x509-certificate-monitor-entry";
091
092
093
094  /**
095   * The name of the attribute that holds the alias used to identify the
096   * certificate in the key store.
097   */
098  @NotNull private static final String ATTR_ALIAS = "alias";
099
100
101
102  /**
103   * The name of the attribute that holds the name of the component with which
104   * the certificate is associated.
105   */
106  @NotNull private static final String ATTR_COMPONENT_NAME = "component-name";
107
108
109
110  /**
111   * The name of the attribute that holds the type of component with which the
112   * certificate is associated.
113   */
114  @NotNull private static final String ATTR_COMPONENT_TYPE = "component-type";
115
116
117
118  /**
119   * The name of the attribute that holds the context type for the certificate.
120   */
121  @NotNull private static final String ATTR_CONTEXT_TYPE = "context-type";
122
123
124
125  /**
126   * The name of the attribute that indicates whether the certificate is
127   * currently within its validity time window.
128   */
129  @NotNull private static final String ATTR_CURRENTLY_VALID = "currently-valid";
130
131
132
133  /**
134   * The name of the attribute that holds the names of any components that
135   * depend on the certificate.
136   */
137  @NotNull private static final String ATTR_DEPENDENT_COMPONENT =
138       "dependent-component";
139
140
141
142  /**
143   * The name of the attribute that holds a human-readable length of time until
144   * the certificate expires.
145   */
146  @NotNull private static final String
147       ATTR_HUMAN_READABLE_TIME_UNTIL_EXPIRATION = "expires";
148
149
150
151  /**
152   * The name of the attribute that holds the reason that the certificate is
153   * considered invalid.
154   */
155  @NotNull private static final String ATTR_INVALID_REASON = "invalid-reason";
156
157
158
159  /**
160   * The name of the attribute that holds the issuer certificate's subject DN.
161   */
162  @NotNull private static final String ATTR_ISSUER_SUBJECT_DN = "issuer";
163
164
165
166  /**
167   * The name of the attribute that holds the path to the key store file in
168   * which the certificate is held.
169   */
170  @NotNull private static final String ATTR_KEY_STORE_FILE = "keystore-file";
171
172
173
174  /**
175   * The name of the attribute that holds the type of key store in which the
176   * certificate is held.
177   */
178  @NotNull private static final String ATTR_KEY_STORE_TYPE = "keystore-type";
179
180
181
182  /**
183   * The name of the attribute that holds the certificate's notAfter timestamp.
184   */
185  @NotNull private static final String ATTR_NOT_VALID_AFTER = "not-valid-after";
186
187
188
189  /**
190   * The name of the attribute that holds the certificate's notBefore timestamp.
191   */
192  @NotNull private static final String ATTR_NOT_VALID_BEFORE =
193       "not-valid-before";
194
195
196
197  /**
198   * The name of the attribute that holds generic property values for the
199   * certificate.
200   */
201  @NotNull private static final String ATTR_PROPERTY = "property";
202
203
204
205  /**
206   * The name of the attribute that holds type of provider in which the
207   * certificate is held.
208   */
209  @NotNull private static final String ATTR_PROVIDER_TYPE = "provider-type";
210
211
212
213  /**
214   * The name of the attribute that holds the number of seconds until
215   * the certificate expires.
216   */
217  @NotNull private static final String ATTR_SECONDS_UNTIL_EXPIRATION =
218       "expires-seconds";
219
220
221
222  /**
223   * The name of the attribute that holds the certificate's serial number.
224   */
225  @NotNull private static final String ATTR_SERIAL_NUMBER = "serial-number";
226
227
228
229  /**
230   * The name of the attribute that holds the certificate's subject DN.
231   */
232  @NotNull private static final String ATTR_SUBJECT_DN = "subject";
233
234
235
236  /**
237   * The serial version UID for this serializable class.
238   */
239  private static final long serialVersionUID = -750858825553972559L;
240
241
242
243  // Indicates whether the certificate is currently within its validity window.
244  @Nullable private final Boolean currentlyValid;
245
246  // The notAfter timestamp for the certificate.
247  @Nullable private final Date notValidAfter;
248
249  // The notBefore timestamp for the certificate.
250  @Nullable private final Date notValidBefore;
251
252  // A list of components that depend on the certificate.
253  @NotNull private final List<String> dependentComponents;
254
255  // A list of context-specific properties for the certificate.
256  @NotNull private final List<String> properties;
257
258  // The number of seconds until the certificate expires.
259  @Nullable private final Long secondsUntilExpiration;
260
261  // The alias used to identify the certificate in the associated key store.
262  @Nullable private final String alias;
263
264  // The name of the component with which the certificate is associated.
265  @Nullable private final String componentName;
266
267  // The type of the component with which the certificate is associated.
268  @Nullable private final String componentType;
269
270  // The type of the context type for the certificate.
271  @Nullable private final String contextType;
272
273  // A human-readable length of time until the certificate expires.
274  @Nullable private final String humanReadableTimeUntilExpiration;
275
276  // A reason that the certificate is not considered valid.
277  @Nullable private final String invalidReason;
278
279  // The subject DN for the certificate's issuer.
280  @Nullable private final String issuerSubjectDN;
281
282  // The path to the key store file in which the certificate is held.
283  @Nullable private final String keyStoreFile;
284
285  // The type of key store in which the certificate is held.
286  @Nullable private final String keyStoreType;
287
288  // The type of provider in which the certificate is held.
289  @Nullable private final String providerType;
290
291  // A string representation of the certificate's serial number.
292  @Nullable private final String serialNumber;
293
294  // The certificate's subject DN.
295  @Nullable private final String subjectDN;
296
297
298
299  /**
300   * Creates a new X.509 certificate monitor entry from the provided entry.
301   *
302   * @param  entry  The entry to be parsed as an X.509 certificate monitor
303   *                entry.  It must not be {@code null}.
304   */
305  public X509CertificateMonitorEntry(@NotNull final Entry entry)
306  {
307    super(entry);
308
309    subjectDN = getString(ATTR_SUBJECT_DN);
310    issuerSubjectDN = getString(ATTR_ISSUER_SUBJECT_DN);
311    notValidBefore = getDate(ATTR_NOT_VALID_BEFORE);
312    notValidAfter = getDate(ATTR_NOT_VALID_AFTER);
313    secondsUntilExpiration = getLong(ATTR_SECONDS_UNTIL_EXPIRATION);
314    humanReadableTimeUntilExpiration =
315         getString(ATTR_HUMAN_READABLE_TIME_UNTIL_EXPIRATION);
316    currentlyValid = getBoolean(ATTR_CURRENTLY_VALID);
317    invalidReason = getString(ATTR_INVALID_REASON);
318    serialNumber = getString(ATTR_SERIAL_NUMBER);
319    contextType = getString(ATTR_CONTEXT_TYPE);
320    componentType = getString(ATTR_COMPONENT_TYPE);
321    componentName = getString(ATTR_COMPONENT_NAME);
322    keyStoreType = getString(ATTR_KEY_STORE_TYPE);
323    keyStoreFile = getString(ATTR_KEY_STORE_FILE);
324    alias = getString(ATTR_ALIAS);
325    providerType = getString(ATTR_PROVIDER_TYPE);
326    dependentComponents = getStrings(ATTR_DEPENDENT_COMPONENT);
327    properties = getStrings(ATTR_PROPERTY);
328  }
329
330
331
332  /**
333   * Retrieves the subject DN for the certificate.
334   *
335   * @return  The subject DN for the certificate, or {@code null} if it was not
336   *          included in the monitor entry.
337   */
338  @Nullable()
339  public String getSubjectDN()
340  {
341    return subjectDN;
342  }
343
344
345
346  /**
347   * Retrieves the subject DN for the certificate's issuer.
348   *
349   * @return  The subject DN for the certificate's issuer, or {@code null} if it
350   *          was not included in the monitor entry.
351   */
352  @Nullable()
353  public String getIssuerSubjectDN()
354  {
355    return issuerSubjectDN;
356  }
357
358
359
360  /**
361   * Retrieves the earliest time that the certificate should be considered
362   * valid.
363   *
364   * @return  The earliest time that the certificate should be considered valid,
365   *          or {@code null} if it was not included in the monitor entry.
366   */
367  @Nullable()
368  public Date getNotValidBefore()
369  {
370    return notValidBefore;
371  }
372
373
374
375  /**
376   * Retrieves the latest time that the certificate should be considered
377   * valid.
378   *
379   * @return  The latest time that the certificate should be considered valid,
380   *          or {@code null} if it was not included in the monitor entry.
381   */
382  @Nullable()
383  public Date getNotValidAfter()
384  {
385    return notValidAfter;
386  }
387
388
389
390  /**
391   * Retrieves the length of time in seconds until the certificate expires.
392   *
393   * @return  The length of time in seconds until the certificate expires, or
394   *          {@code null} if it was not included in the monitor entry.
395   */
396  @Nullable()
397  public Long getSecondsUntilExpiration()
398  {
399    return secondsUntilExpiration;
400  }
401
402
403
404  /**
405   * Retrieves a human-readable representation of the length of time until the
406   * certificate expires.
407   *
408   * @return  A human-readable representation of the length of time until the
409   *          certificate expires, or {@code null} if it was not included in the
410   *          monitor entry.
411   */
412  @Nullable()
413  public String getHumanReadableTimeUntilExpiration()
414  {
415    return humanReadableTimeUntilExpiration;
416  }
417
418
419
420  /**
421   * Indicates whether the certificate is currently within its validity window.
422   *
423   * @return  {@code Boolean.TRUE} if the certificate is within its validity
424   *          window, {@code Boolean.FALSE} if it is outside its validity
425   *          window, or {@code null} if it was not included in the monitor
426   *          entry.
427   */
428  @Nullable()
429  public Boolean getCurrentlyValid()
430  {
431    return currentlyValid;
432  }
433
434
435
436  /**
437   * Retrieves the reason that the certificate is considered invalid.
438   *
439   * @return  The reason that the certificate is considered invalid, or
440   *          {@code null} if it was not included in the monitor entry.
441   */
442  @Nullable()
443  public String getInvalidReason()
444  {
445    return invalidReason;
446  }
447
448
449
450  /**
451   * Retrieves a string representation of the certificate's serial number.
452   *
453   * @return  A string representation of the certificate's serial number, or
454   *          {@code null} if it was not included in the monitor entry.
455   */
456  @Nullable()
457  public String getSerialNumber()
458  {
459    return serialNumber;
460  }
461
462
463
464  /**
465   * Retrieves the context in which the certificate is being used.
466   *
467   * @return  The context in which the certificate is being used, or
468   *          {@code null} if it was not included in the monitor entry.
469   */
470  @Nullable()
471  public String getContextType()
472  {
473    return contextType;
474  }
475
476
477
478  /**
479   * Retrieves the type of component with which the certificate is associated.
480   *
481   * @return  The type of component with which the certificate is associated, or
482   *          {@code null} if it was not included in the monitor entry.
483   */
484  @Nullable()
485  public String getComponentType()
486  {
487    return componentType;
488  }
489
490
491
492  /**
493   * Retrieves the name of the component with which the certificate is
494   * associated.
495   *
496   * @return  The name of the component with which the certificate is
497   *          associated, or {@code null} if it was not included in the monitor
498   *          entry.
499   */
500  @Nullable()
501  public String getComponentName()
502  {
503    return componentName;
504  }
505
506
507
508  /**
509   * Retrieves the type of key store in which the certificate is held.
510   *
511   * @return  The type of key store in which the certificate is held, or
512   *          {@code null} if it was not included in the monitor entry.
513   */
514  @Nullable()
515  public String getKeyStoreType()
516  {
517    return keyStoreType;
518  }
519
520
521
522  /**
523   * Retrieves the path to the key store file in which the certificate is held.
524   *
525   * @return  The path to the key store file in which the certificate is held,
526   *          or {@code null} if it was not included in the monitor entry.
527   */
528  @Nullable()
529  public String getKeyStoreFile()
530  {
531    return keyStoreFile;
532  }
533
534
535
536  /**
537   * Retrieves the alias used to identify the certificate in the key store.
538   *
539   * @return  The alias used to identify the certificate in the key store, or
540   *          {@code null} if it was not included in the monitor entry.
541   */
542  @Nullable()
543  public String getAlias()
544  {
545    return alias;
546  }
547
548
549
550  /**
551   * Retrieves the type of provider in which the certificate is held.
552   *
553   * @return  The type of provider in which the certificate is held, or
554   *          {@code null} if it was not included in the monitor entry.
555   */
556  @Nullable()
557  public String getProviderType()
558  {
559    return providerType;
560  }
561
562
563
564  /**
565   * Retrieves the names of any components that depend on the certificate.
566   *
567   * @return  The names of any components that depend on the certificate, or an
568   *          empty list if it was not included in the monitor entry.
569   */
570  @NotNull()
571  public List<String> getDependentComponents()
572  {
573    return dependentComponents;
574  }
575
576
577
578  /**
579   * Retrieves a list of context-specific properties for the certificate.
580   *
581   * @return  A list of context-specific properties for the certificate, or an
582   *          empty list if it was not included in the monitor entry.
583   */
584  @NotNull()
585  public List<String> getProperties()
586  {
587    return properties;
588  }
589
590
591
592  /**
593   * {@inheritDoc}
594   */
595  @Override()
596  @NotNull()
597  public String getMonitorDisplayName()
598  {
599    return INFO_X509_CERTIFICATE_MONITOR_DISPNAME.get();
600  }
601
602
603
604  /**
605   * {@inheritDoc}
606   */
607  @Override()
608  @NotNull()
609  public String getMonitorDescription()
610  {
611    return INFO_X509_CERTIFICATE_MONITOR_DESC.get();
612  }
613
614
615
616  /**
617   * {@inheritDoc}
618   */
619  @Override()
620  @NotNull()
621  public Map<String,MonitorAttribute> getMonitorAttributes()
622  {
623    final LinkedHashMap<String,MonitorAttribute> attrs = new LinkedHashMap<>();
624
625    if (subjectDN != null)
626    {
627      addMonitorAttribute(attrs,
628           ATTR_SUBJECT_DN,
629           INFO_X509_CERTIFICATE_DISPNAME_SUBJECT_DN.get(),
630           INFO_X509_CERTIFICATE_DESC_SUBJECT_DN.get(),
631           subjectDN);
632    }
633
634    if (issuerSubjectDN != null)
635    {
636      addMonitorAttribute(attrs,
637           ATTR_ISSUER_SUBJECT_DN,
638           INFO_X509_CERTIFICATE_DISPNAME_ISSUER_DN.get(),
639           INFO_X509_CERTIFICATE_DESC_ISSUER_DN.get(),
640           issuerSubjectDN);
641    }
642
643    if (notValidBefore != null)
644    {
645      addMonitorAttribute(attrs,
646           ATTR_NOT_VALID_BEFORE,
647           INFO_X509_CERTIFICATE_DISPNAME_NOT_BEFORE.get(),
648           INFO_X509_CERTIFICATE_DESC_NOT_BEFORE.get(),
649           notValidBefore);
650    }
651
652    if (notValidAfter != null)
653    {
654      addMonitorAttribute(attrs,
655           ATTR_NOT_VALID_AFTER,
656           INFO_X509_CERTIFICATE_DISPNAME_NOT_AFTER.get(),
657           INFO_X509_CERTIFICATE_DESC_NOT_AFTER.get(),
658           notValidAfter);
659    }
660
661    if (secondsUntilExpiration != null)
662    {
663      addMonitorAttribute(attrs,
664           ATTR_SECONDS_UNTIL_EXPIRATION,
665           INFO_X509_CERTIFICATE_DISPNAME_SECONDS_UNTIL_EXPIRATION.get(),
666           INFO_X509_CERTIFICATE_DESC_SECONDS_UNTIL_EXPIRATION.get(),
667           secondsUntilExpiration);
668    }
669
670    if (humanReadableTimeUntilExpiration != null)
671    {
672      addMonitorAttribute(attrs,
673           ATTR_HUMAN_READABLE_TIME_UNTIL_EXPIRATION,
674           INFO_X509_CERTIFICATE_DISPNAME_TIME_UNTIL_EXPIRATION.get(),
675           INFO_X509_CERTIFICATE_DESC_TIME_UNTIL_EXPIRATION.get(),
676           humanReadableTimeUntilExpiration);
677    }
678
679    if (currentlyValid != null)
680    {
681      addMonitorAttribute(attrs,
682           ATTR_CURRENTLY_VALID,
683           INFO_X509_CERTIFICATE_DISPNAME_CURRENTLY_VALID.get(),
684           INFO_X509_CERTIFICATE_DESC_CURRENTLY_VALID.get(),
685           currentlyValid);
686    }
687
688    if (invalidReason != null)
689    {
690      addMonitorAttribute(attrs,
691           ATTR_INVALID_REASON,
692           INFO_X509_CERTIFICATE_DISPNAME_INVALID_REASON.get(),
693           INFO_X509_CERTIFICATE_DESC_INVALID_REASON.get(),
694           invalidReason);
695    }
696
697    if (serialNumber != null)
698    {
699      addMonitorAttribute(attrs,
700           ATTR_SERIAL_NUMBER,
701           INFO_X509_CERTIFICATE_DISPNAME_SERIAL_NUMBER.get(),
702           INFO_X509_CERTIFICATE_DESC_SERIAL_NUMBER.get(),
703           serialNumber);
704    }
705
706    if (contextType != null)
707    {
708      addMonitorAttribute(attrs,
709           ATTR_CONTEXT_TYPE,
710           INFO_X509_CERTIFICATE_DISPNAME_CONTEXT_TYPE.get(),
711           INFO_X509_CERTIFICATE_DESC_CONTEXT_TYPE.get(),
712           contextType);
713    }
714
715    if (componentType != null)
716    {
717      addMonitorAttribute(attrs,
718           ATTR_COMPONENT_TYPE,
719           INFO_X509_CERTIFICATE_DISPNAME_COMPONENT_TYPE.get(),
720           INFO_X509_CERTIFICATE_DESC_COMPONENT_TYPE.get(),
721           componentType);
722    }
723
724    if (componentName != null)
725    {
726      addMonitorAttribute(attrs,
727           ATTR_COMPONENT_NAME,
728           INFO_X509_CERTIFICATE_DISPNAME_COMPONENT_NAME.get(),
729           INFO_X509_CERTIFICATE_DESC_COMPONENT_NAME.get(),
730           componentName);
731    }
732
733    if (keyStoreType != null)
734    {
735      addMonitorAttribute(attrs,
736           ATTR_KEY_STORE_TYPE,
737           INFO_X509_CERTIFICATE_DISPNAME_KEY_STORE_TYPE.get(),
738           INFO_X509_CERTIFICATE_DESC_KEY_STORE_TYPE.get(),
739           keyStoreType);
740    }
741
742    if (keyStoreFile != null)
743    {
744      addMonitorAttribute(attrs,
745           ATTR_KEY_STORE_FILE,
746           INFO_X509_CERTIFICATE_DISPNAME_KEY_STORE_FILE.get(),
747           INFO_X509_CERTIFICATE_DESC_KEY_STORE_FILE.get(),
748           keyStoreFile);
749    }
750
751    if (alias != null)
752    {
753      addMonitorAttribute(attrs,
754           ATTR_ALIAS,
755           INFO_X509_CERTIFICATE_DISPNAME_ALIAS.get(),
756           INFO_X509_CERTIFICATE_DESC_ALIAS.get(),
757           alias);
758    }
759
760    if (providerType != null)
761    {
762      addMonitorAttribute(attrs,
763           ATTR_PROVIDER_TYPE,
764           INFO_X509_CERTIFICATE_DISPNAME_PROVIDER_TYPE.get(),
765           INFO_X509_CERTIFICATE_DESC_PROVIDER_TYPE.get(),
766           providerType);
767    }
768
769    if (! dependentComponents.isEmpty())
770    {
771      addMonitorAttribute(attrs,
772           ATTR_DEPENDENT_COMPONENT,
773           INFO_X509_CERTIFICATE_DISPNAME_DEPENDENT_COMPONENT.get(),
774           INFO_X509_CERTIFICATE_DESC_DEPENDENT_COMPONENT.get(),
775           dependentComponents);
776    }
777
778    if (! properties.isEmpty())
779    {
780      addMonitorAttribute(attrs,
781           ATTR_PROPERTY,
782           INFO_X509_CERTIFICATE_DISPNAME_PROPERTY.get(),
783           INFO_X509_CERTIFICATE_DESC_PROPERTY.get(),
784           properties);
785    }
786
787    return Collections.unmodifiableMap(attrs);
788  }
789}