1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18/** 19* @author Alexander Y. Kleymenov 20* @version $Revision$ 21*/ 22 23package org.apache.harmony.security.x509; 24 25import java.util.Arrays; 26import org.apache.harmony.security.asn1.ASN1Any; 27import org.apache.harmony.security.asn1.ASN1Oid; 28import org.apache.harmony.security.asn1.ASN1Sequence; 29import org.apache.harmony.security.asn1.ASN1Type; 30import org.apache.harmony.security.asn1.BerInputStream; 31import org.apache.harmony.security.asn1.ObjectIdentifier; 32import org.apache.harmony.security.utils.AlgNameMapper; 33 34 35/** 36 * The class encapsulates the ASN.1 DER encoding/decoding work 37 * with the Algorithm Identifier which is a part of X.509 certificate 38 * (as specified in RFC 3280 - 39 * Internet X.509 Public Key Infrastructure. 40 * Certificate and Certificate Revocation List (CRL) Profile. 41 * http://www.ietf.org/rfc/rfc3280.txt): 42 * 43 * <pre> 44 * AlgorithmIdentifier ::= SEQUENCE { 45 * algorithm OBJECT IDENTIFIER, 46 * parameters ANY DEFINED BY algorithm OPTIONAL 47 * } 48 * </pre> 49 */ 50public final class AlgorithmIdentifier { 51 /** the value of algorithm field */ 52 private String algorithm; 53 /** the name of the algorithm */ 54 private String algorithmName; 55 /** the value of parameters field */ 56 private byte[] parameters; 57 /** the encoding of AlgorithmIdentifier value */ 58 private byte[] encoding; 59 60 public AlgorithmIdentifier(String algorithm) { 61 this(algorithm, null, null); 62 } 63 64 public AlgorithmIdentifier(String algorithm, byte[] parameters) { 65 this(algorithm, parameters, null); 66 } 67 68 private AlgorithmIdentifier(String algorithm, byte[] parameters, byte[] encoding) { 69 this.algorithm = algorithm; 70 this.parameters = parameters; 71 this.encoding = encoding; 72 } 73 74 /** 75 * For testing when algorithmName is not known, but algorithm OID is. 76 */ 77 public AlgorithmIdentifier(String algorithm, String algorithmName) { 78 this(algorithm, null, null); 79 this.algorithmName = algorithmName; 80 } 81 82 /** 83 * Returns the value of algorithm field of the structure. 84 */ 85 public String getAlgorithm() { 86 return algorithm; 87 } 88 89 /** 90 * Returns the name of the algorithm corresponding to 91 * its OID. If there is no the such correspondence, 92 * algorithm OID is returned. 93 */ 94 public String getAlgorithmName() { 95 if (algorithmName == null) { 96 algorithmName = AlgNameMapper.map2AlgName(algorithm); 97 if (algorithmName == null) { 98 algorithmName = algorithm; 99 } 100 } 101 return algorithmName; 102 } 103 104 /** 105 * Returns the value of parameters field of the structure. 106 */ 107 public byte[] getParameters() { 108 return parameters; 109 } 110 111 /** 112 * Returns ASN.1 encoded form of this X.509 AlgorithmIdentifier value. 113 */ 114 public byte[] getEncoded() { 115 if (encoding == null) { 116 encoding = ASN1.encode(this); 117 } 118 return encoding; 119 } 120 121 @Override public boolean equals(Object ai) { 122 if (!(ai instanceof AlgorithmIdentifier)) { 123 return false; 124 } 125 AlgorithmIdentifier algid = (AlgorithmIdentifier) ai; 126 return (algorithm.equals(algid.algorithm)) 127 && ((parameters == null) 128 ? algid.parameters == null 129 : Arrays.equals(parameters, algid.parameters)); 130 } 131 132 @Override public int hashCode() { 133 return algorithm.hashCode() * 37 + (parameters != null ? Arrays.hashCode(parameters) : 0); 134 } 135 136 public void dumpValue(StringBuilder sb) { 137 sb.append(getAlgorithmName()); 138 if (parameters == null) { 139 sb.append(", no params, "); 140 } else { 141 sb.append(", params unparsed, "); 142 } 143 sb.append("OID = "); 144 sb.append(getAlgorithm()); 145 } 146 147 /** 148 * Custom AlgorithmIdentifier DER encoder/decoder 149 */ 150 public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] { 151 ASN1Oid.getInstance(), ASN1Any.getInstance() }) { 152 { 153 setOptional(1); // parameters are optional 154 } 155 156 @Override protected Object getDecodedObject(BerInputStream in) { 157 Object[] values = (Object[]) in.content; 158 return new AlgorithmIdentifier(ObjectIdentifier 159 .toString((int[]) values[0]), (byte[]) values[1]); 160 } 161 162 @Override protected void getValues(Object object, Object[] values) { 163 164 AlgorithmIdentifier aID = (AlgorithmIdentifier) object; 165 166 values[0] = ObjectIdentifier.toIntArray(aID.getAlgorithm()); 167 values[1] = aID.getParameters(); 168 } 169 }; 170} 171