package model.pki; import model.asn1.ASN1Object; import model.asn1.ObjectIdentifier; import model.asn1.Tag; import model.asn1.exceptions.ParseException; import model.asn1.parsing.BytesReader; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.stream.Stream; /** * Implements the following: *
* AttributeTypeAndValue ::= SEQUENCE { * type ATTRIBUTE.&id({SupportedAttributes}), * value ATTRIBUTE.&Type({SupportedAttributes}{@type}) OPTIONAL, * ... } **/ public class AlgorithmIdentifier extends ASN1Object { /** * The type of that attribute. For example,
1.2.840.113549.1.1.11is sha256WithRSAEncryption. */ private final ObjectIdentifier type; /** * Additional parameters for that algorithm. Optional, and could be ASN.1 NULL or Java null (absent). * According to RFC8017$A.2, it should be NULL for a number of algorithms: *
* PKCS1Algorithms ALGORITHM-IDENTIFIER ::= { * { OID rsaEncryption PARAMETERS NULL } | * { OID md2WithRSAEncryption PARAMETERS NULL } | * { OID md5WithRSAEncryption PARAMETERS NULL } | * { OID sha1WithRSAEncryption PARAMETERS NULL } | * { OID sha224WithRSAEncryption PARAMETERS NULL } | * { OID sha256WithRSAEncryption PARAMETERS NULL } | * { OID sha384WithRSAEncryption PARAMETERS NULL } | * { OID sha512WithRSAEncryption PARAMETERS NULL } | * { OID sha512-224WithRSAEncryption PARAMETERS NULL } | * { OID sha512-256WithRSAEncryption PARAMETERS NULL } | * { OID id-RSAES-OAEP PARAMETERS RSAES-OAEP-params } | * PKCS1PSourceAlgorithms | * { OID id-RSASSA-PSS PARAMETERS RSASSA-PSS-params }, * ... -- Allows for future expansion -- * } **/ private final ASN1Object parameters; /** * EFFECT: Init the object with tag, parentTag, type, and parameters. For tag and parentTag, see {@link ASN1Object}. * REQUIRES: The values must match the type. Type tag should be UNIVERSAL OID. Parameters nullable. */ public AlgorithmIdentifier(Tag tag, Tag parentTag, ObjectIdentifier type, ASN1Object parameters) { super(tag, parentTag); this.type = type; this.parameters = parameters; } /** * EFFECTS: Parse input DER. Parameters are not checked against the type. * Throws {@link ASN1Object} if invalid: * - Any fields missing * - Any fields having an incorrect tag (as seen in the ASN.1 definition) * - Any fields with encoding instructions that violate implicit / explicit encoding rules * - Other issues found during parsing the object, like early EOF (see {@link ASN1Object}) * MODIFIES: this, encoded */ public AlgorithmIdentifier(BytesReader encoded, boolean hasParentTag) throws ParseException { super(encoded, hasParentTag); int i = encoded.getIndex(); this.type = new ObjectIdentifier(encoded, false); this.type.getTag().enforce(ObjectIdentifier.TAG); i = encoded.getIndex() - i; if (getLength() > i) { this.parameters = ASN1Object.parse(encoded, false); } else { this.parameters = null; } } /** * EFFECTS: Encode the fields into DER, in the order. */ @Override public Byte[] encodeValueDER() { return Stream.of(Arrays.asList(type.encodeDER()), parameters == null ? Collections.