/** * Gets the common name attribute (CN) of the certificate subject distinguished name. * * @param cert Certificate to examine. * * @return Subject CN or null if no CN attribute is defined in the subject DN. * * @throws EncodingException on cert field extraction. */ public static String subjectCN(final X509Certificate cert) throws EncodingException { return new NameReader(cert).readSubject().getValue(StandardAttributeType.CommonName); }
/** * Adds an attribute by type and value to the end of the attribute list. * * @param typeOid OID of attribute type. * @param value Attribute value. */ public void add(final String typeOid, final String value) { final StandardAttributeType type = StandardAttributeType.fromOid(typeOid); if (type != null) { add(new Attribute(type, value)); } else { add(new Attribute(new UnknownAttributeType(typeOid), value)); } }
/** * Gets the attribute type whose name is the given string. * * @param name Name of attribute to get, where the name is the all-caps RFC/standard name that would be returned by * {@link #getName()} for the desired attribute. * * @return Attribute type whose {@link #getName()} property matches the given value or null if there is no standard * attribute with the given name. */ public static AttributeType fromName(final String name) { for (AttributeType t : StandardAttributeType.values()) { if (t.getName().equals(name)) { return t; } } return null; } }
/** * Find an RDN with the specified OID. * * @param sequence the DN components * @param oid the OID to look for * * @return the first matching RDN value, or null */ @Nullable protected String findRDN(@Nonnull final RDNSequence sequence, @Nonnull @NotEmpty final String oid) { // We use backward() here because otherwise the library returns attributes in least to most-specific order. for (final RDN rdn : sequence.backward()) { for (final Attribute attribute : rdn.getAttributes()) { if (attribute.getType().getOid().equals(oid)) { return attribute.getValue(); } } } return null; }
@Override public String format(final X500Principal dn) { final StringBuilder builder = new StringBuilder(); final RDNSequence sequence = NameReader.readX500Principal(dn); int i = 0; for (RDN rdn : sequence.backward()) { if (i++ > 0) { builder.append(RDN_SEPARATOR); } int j = 0; for (Attribute attr : rdn.getAttributes()) { if (j++ > 0) { builder.append(ATV_SEPARATOR); } builder.append(attr.getType()).append('='); final AttributeType type = attr.getType(); if (type instanceof StandardAttributeType) { escape(attr.getValue(), builder); } else { encode(attr.getValue(), builder); } } } return builder.toString(); }
/** * Creates a comma-separated list of TYPE=VALUE tokens from the attributes in the list in order. * * @return String representation that resembles an X.509 distinguished name, e.g. <code>CN=foo, OU=Bar, dc=example, * dc=com</code>. */ @Override public String toString() { final StringBuilder builder = new StringBuilder(); int i = 0; for (RDN rdn : this) { for (Attribute attr : rdn.getAttributes()) { if (i++ > 0) { builder.append(", "); } builder.append(attr.getType()).append('=').append(attr.getValue()); } } return builder.toString(); } }
@Override protected String resolvePrincipalInternal(final X509Certificate certificate) { LOGGER.debug("Resolving principal for [{}]", certificate); val sb = new StringBuffer(); val m = ATTR_PATTERN.matcher(this.descriptor); val attrMap = new HashMap<String, AttributeContext>(); val rdnSequence = new NameReader(certificate).readSubject(); while (m.find()) { val name = m.group(1); if (!attrMap.containsKey(name)) { val values = getAttributeValues(rdnSequence, StandardAttributeType.fromName(name)); attrMap.put(name, new AttributeContext(values)); } val context = attrMap.get(name); m.appendReplacement(sb, context.nextValue()); } m.appendTail(sb); return sb.toString(); }
/** * Gets the first value of the given type that appears in the attribute list. * * @param type Attribute type. * * @return Value of first attribute of given type or null if no attributes of given type exist. */ public String getValue(final AttributeType type) { for (Attribute attr : attributes) { if (attr.getType().equals(type)) { return attr.getValue(); } } return null; }
/** * Gets an immutable list of all attributes of the given type. The order of the returned list reflects the ordering of * the RDNs and their attributes. * * @param type Attribute type. * * @return Non-null list of attributes of given type. An empty list is returned if there are no attributes of the * given type. */ public List<String> getValues(final AttributeType type) { final List<String> values = new ArrayList<>(rdns.size()); for (RDN rdn : rdns) { values.addAll(rdn.getAttributes().getValues(type)); } return Collections.unmodifiableList(values); }
/** * Converts the given X.500 principal to a list of relative distinguished names that contains the attributes * comprising the DN. * * @param principal Principal to convert. * * @return X500 principal as an RDN sequence. */ public static RDNSequence readX500Principal(final X500Principal principal) { final X500Name name = X500Name.getInstance(principal.getEncoded()); final RDNSequence sequence = new RDNSequence(); for (org.bouncycastle.asn1.x500.RDN rdn : name.getRDNs()) { final Attributes attributes = new Attributes(); for (AttributeTypeAndValue tv : rdn.getTypesAndValues()) { attributes.add(tv.getType().getId(), tv.getValue().toString()); } sequence.add(new RDN(attributes)); } return sequence; } }
/** * Gets an immutable list of all attributes of the given type. The order of the returned list reflects the ordering of * the underlying attributes. * * @param type Attribute type. * * @return Non-null list of attributes of given type. An empty list is returned if there are no attributes of the * given type. */ public List<String> getValues(final AttributeType type) { final List<String> values = new ArrayList<>(attributes.size()); values.addAll( attributes.stream().filter( attr -> attr.getType().equals(type)).map(Attribute::getValue).collect(Collectors.toList())); return Collections.unmodifiableList(values); }
/** * Reads the subject field from the certificate. * * @return Subject DN as an RDN sequence. */ public RDNSequence readSubject() { return readX500Principal(certificate.getSubjectX500Principal()); }
/** * Gets the attribute type whose OID is the given string. * * @param oid OID of attribute type to get. * * @return Attribute type whose OID matches given value or none if there is no standard attribute type matching the * given OID. */ public static StandardAttributeType fromOid(final String oid) { for (StandardAttributeType t : StandardAttributeType.values()) { if (t.getOid().equals(oid)) { return t; } } return null; }
/** * Gets the first value of the given type that appears in the attribute list of any RDN in the sequence. * * @param type Attribute type. * * @return Value of first attribute of given type or null if no attributes of given type exist. */ public String getValue(final AttributeType type) { final List<String> values = getValues(type); if (values.size() > 0) { return values.get(0); } return null; }
/** * Gets the values of the given attribute contained in the DN. * <p> * <p><strong>NOTE:</strong> no escaping is done on special characters in the * values, which could be different from what would appear in the string * representation of the DN.</p> * Iterates sequence in reverse order as specified in section 2.1 of RFC 2253. * * @param rdnSequence list of relative distinguished names * that contains the attributes comprising the DN. * @param attribute Attribute whose values will be retrieved. * @return The attribute values for the given attribute in the order they * appear would appear in the string representation of the DN or an empty * array if the given attribute does not exist. */ private static String[] getAttributeValues(final RDNSequence rdnSequence, final AttributeType attribute) { val values = new ArrayList<String>(); for (val rdn : rdnSequence.backward()) { for (val attr : rdn.getAttributes()) { if (attr.getType().equals(attribute)) { values.add(attr.getValue()); } } } return values.toArray(ArrayUtils.EMPTY_STRING_ARRAY); }
final Matcher m = ATTR_PATTERN.matcher(this.descriptor); final Map<String, AttributeContext> attrMap = new HashMap<>(); final RDNSequence rdnSequence = new NameReader(certificate).readSubject(); String name; String[] values; if (!attrMap.containsKey(name)) { values = getAttributeValues(rdnSequence, StandardAttributeType.fromName(name)); attrMap.put(name, new AttributeContext(name, values));
/** * Reads the issuer field from the certificate. * * @return Issuer DN as an RDN sequence. */ public RDNSequence readIssuer() { return readX500Principal(certificate.getIssuerX500Principal()); }
/** * Gets the values of the given attribute contained in the DN. * * <p><strong>NOTE:</strong> no escaping is done on special characters in the * values, which could be different from what would appear in the string * representation of the DN.</p> * * @param rdnSequence list of relative distinguished names * that contains the attributes comprising the DN. * @param attribute Attribute whose values will be retrieved. * @return The attribute values for the given attribute in the order they * appear would appear in the string representation of the DN or an empty * array if the given attribute does not exist. */ private static String[] getAttributeValues(final RDNSequence rdnSequence, final AttributeType attribute) { // Iterates sequence in reverse order as specified in section 2.1 of RFC 2253 final List<String> values = new ArrayList<>(); for (final RDN rdn : rdnSequence.backward()) { for (final Attribute attr : rdn.getAttributes()) { if (attr.getType().equals(attribute)) { values.add(attr.getValue()); } } } return values.toArray(new String[values.size()]); }
final RDNSequence dnAttrs = NameReader.readX500Principal(x500Principal); for (final String oid : objectIds) { final String rdn = findRDN(dnAttrs, oid);