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 23 package org.apache.harmony.security.x509; 24 25 import java.util.Arrays; 26 import org.apache.harmony.security.asn1.ASN1Any; 27 import org.apache.harmony.security.asn1.ASN1Oid; 28 import org.apache.harmony.security.asn1.ASN1Sequence; 29 import org.apache.harmony.security.asn1.ASN1Type; 30 import org.apache.harmony.security.asn1.BerInputStream; 31 import org.apache.harmony.security.asn1.ObjectIdentifier; 32 import 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 */ 50 public class AlgorithmIdentifier { 51 52 // the value of algorithm field 53 private String algorithm; 54 // the name of the algorithm 55 private String algorithmName; 56 // the value of parameters field 57 private byte[] parameters; 58 // the encoding of AlgorithmIdentifier value 59 private byte[] encoding; 60 61 /** 62 * TODO 63 * @param algorithm: String 64 */ 65 public AlgorithmIdentifier(String algorithm) { 66 this(algorithm, null, null); 67 } 68 69 /** 70 * TODO 71 * @param algorithm: String 72 * @param parameters: byte[] 73 */ 74 public AlgorithmIdentifier(String algorithm, byte[] parameters) { 75 this(algorithm, parameters, null); 76 } 77 78 // 79 // TODO 80 // @param algorithm: String 81 // @param parameters: byte[] 82 // @param encoding: byte[] 83 // 84 private AlgorithmIdentifier(String algorithm, byte[] parameters, 85 byte[] encoding) { 86 this.algorithm = algorithm; 87 this.parameters = parameters; 88 this.encoding = encoding; 89 } 90 91 /** 92 * Returns the value of algorithm field of the structure. 93 * @return algorithm 94 */ 95 public String getAlgorithm() { 96 return algorithm; 97 } 98 99 /** 100 * Returns the name of the algorithm corresponding to 101 * its OID. If there is no the such correspondence, 102 * algorithm OID is returned. 103 * @return algorithm 104 */ 105 public String getAlgorithmName() { 106 if (algorithmName == null) { 107 algorithmName = AlgNameMapper.map2AlgName(algorithm); 108 if (algorithmName == null) { 109 algorithmName = algorithm; 110 } 111 } 112 return algorithmName; 113 } 114 115 /** 116 * Returns the value of parameters field of the structure. 117 * @return parameters 118 */ 119 public byte[] getParameters() { 120 return parameters; 121 } 122 123 /** 124 * Returns ASN.1 encoded form of this X.509 AlgorithmIdentifier value. 125 * @return a byte array containing ASN.1 encode form. 126 */ 127 public byte[] getEncoded() { 128 if (encoding == null) { 129 encoding = ASN1.encode(this); 130 } 131 return encoding; 132 } 133 134 public boolean equals(Object ai) { 135 if (!(ai instanceof AlgorithmIdentifier)) { 136 return false; 137 } 138 AlgorithmIdentifier algid = (AlgorithmIdentifier) ai; 139 return (algorithm.equals(algid.algorithm)) 140 && ((parameters == null) 141 ? algid.parameters == null 142 : Arrays.equals(parameters, algid.parameters)); 143 } 144 145 public int hashCode() { 146 return algorithm.hashCode() * 37 + 147 (parameters != null ? parameters.hashCode() : 0); 148 } 149 150 /** 151 * Places the string representation into the StringBuffer object. 152 */ 153 public void dumpValue(StringBuffer buffer) { 154 buffer.append(getAlgorithmName()); 155 if (parameters == null) { 156 buffer.append(", no params, "); 157 } else { 158 buffer.append(", params unparsed, "); 159 } 160 buffer.append("OID = "); 161 buffer.append(getAlgorithm()); 162 } 163 164 /** 165 * Custom AlgorithmIdentifier DER encoder/decoder 166 */ 167 public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] { 168 ASN1Oid.getInstance(), ASN1Any.getInstance() }) { 169 { 170 setOptional(1); // parameters are optional 171 } 172 173 protected Object getDecodedObject(BerInputStream in) { 174 Object[] values = (Object[]) in.content; 175 return new AlgorithmIdentifier(ObjectIdentifier 176 .toString((int[]) values[0]), (byte[]) values[1]); 177 } 178 179 protected void getValues(Object object, Object[] values) { 180 181 AlgorithmIdentifier aID = (AlgorithmIdentifier) object; 182 183 values[0] = ObjectIdentifier.toIntArray(aID.getAlgorithm()); 184 values[1] = aID.getParameters(); 185 } 186 }; 187 188 } 189 190