package model.x501; import model.asn1.ASN1Object; import model.asn1.Encodable; import model.asn1.Tag; import model.asn1.exceptions.ParseException; import model.asn1.parsing.BytesReader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Represents an X.501 directory Name (a.k.a. RDNSequence). *
 *     Name ::= CHOICE { -- only one possibility for now -- rdnSequence RDNSequence }
 *     RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
 *     DistinguishedName ::= RDNSequence
 * 
*/ public class Name extends ASN1Object { private final RelativeDistinguishedName[] rdnSequence; /** * EFFECT: Initialize the Name with the given tags and rdnSequence. For tag and parentTag, consult * {@link ASN1Object}. * REQUIRES: Items should have SET tag. */ public Name(Tag tag, Tag parentTag, RelativeDistinguishedName[] rdnSequence) { super(tag, parentTag); this.rdnSequence = rdnSequence; } /** * EFFECT: Parse the Name from input DER bytes. For details on parsing, refer to {@link ASN1Object}. * Throws {@link ParseException} for invalid input. * MODIFIES: this, encoded */ public Name(BytesReader encoded, boolean hasParentTag) throws ParseException { super(encoded, hasParentTag); final List list = new ArrayList<>(); for (int i = 0; i < getLength();) { int index = encoded.getIndex(); final RelativeDistinguishedName name = new RelativeDistinguishedName(encoded, false); name.getTag().enforce(TAG_SET); list.add(name); index = encoded.getIndex() - index; i += index; } this.rdnSequence = list.toArray(new RelativeDistinguishedName[0]); } /** * EFFECTS: Encode the SEQUENCE OF into DER, keep order. RDNs will be encoded one-by-one. */ @Override public Byte[] encodeValueDER() { return Stream.of(rdnSequence) .map(Encodable::encodeDER) .flatMap(Arrays::stream) .toArray(Byte[]::new); } /** * EFFECT: Convert the name into directory string, like CN=yuuta,OU=users,DC=yuuta,DC=moe */ @Override public String toString() { return Stream.of(rdnSequence) .map(RelativeDistinguishedName::toString) .collect(Collectors.joining(",")); } public RelativeDistinguishedName[] getRdnSequence() { return rdnSequence; } }