org.wildfly.security.asn1.ASN1 Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wildfly.security.asn1;
import static org.wildfly.security.asn1.ElytronMessages.log;
import org.wildfly.common.array.Arrays2;
/**
* A class that contains ASN.1 constants and utilities.
*
* @author Farah Juma
*/
public class ASN1 {
/**
* The universal boolean type tag.
*/
public static final int BOOLEAN_TYPE = 1;
/**
* The universal integer type tag.
*/
public static final int INTEGER_TYPE = 2;
/**
* The universal bit string type tag.
*/
public static final int BIT_STRING_TYPE = 3;
/**
* The universal octet string type tag.
*/
public static final int OCTET_STRING_TYPE = 4;
/**
* The universal null type tag.
*/
public static final int NULL_TYPE = 5;
/**
* The universal object identifier type tag.
*/
public static final int OBJECT_IDENTIFIER_TYPE = 6;
/**
* The universal UTF-8 string type tag.
*/
public static final int UTF8_STRING_TYPE = 12;
/**
* The universal printable string type tag.
*/
public static final int PRINTABLE_STRING_TYPE = 19;
/**
* The universal IA5 string type tag.
*/
public static final int IA5_STRING_TYPE = 22;
/**
* A type for representing timestamps.
*/
public static final int GENERALIZED_TIME_TYPE = 24;
/**
* The universal (UTF-32 big-endian) string type tag.
*/
public static final int UNIVERSAL_STRING_TYPE = 28;
/**
* The universal BMP (UTF-16 big-endian) string type tag.
*/
public static final int BMP_STRING_TYPE = 30;
/**
* The universal sequence type tag.
*/
public static final int SEQUENCE_TYPE = 48;
/**
* The universal set type tag.
*/
public static final int SET_TYPE = 49;
/**
* Mask used to determine if a type tag is constructed.
*/
public static final int CONSTRUCTED_MASK = 0x20;
/**
* Mask used to determine if a type tag is application-specific.
*/
public static final int APPLICATION_SPECIFIC_MASK = 0x40;
/**
* Mask used to determine if a type tag is context-specific.
*/
public static final int CONTEXT_SPECIFIC_MASK = 0x80;
/**
* Mask used to obtain the class bits from a type tag.
*/
public static final int CLASS_MASK = 0xc0;
/**
* Mask used to obtain the tag number bits from a type tag.
*/
public static final int TAG_NUMBER_MASK = 0x1f;
// 1.2.840.10040
/**
* Object identifier for the SHA1 with DSA signature algorithm.
*/
public static final String OID_SHA1_WITH_DSA = "1.2.840.10040.4.3";
/**
* Object identifier for the SHA256 with DSA signature algorithm.
*
* @since 1.2.0
*/
public static final String OID_SHA256_WITH_DSA = "2.16.840.1.101.3.4.3.2";
// 1.2.840.10045
/**
* Object identifier for the SHA1 with ECDSA signature algorithm.
*/
public static final String OID_SHA1_WITH_ECDSA = "1.2.840.10045.4.1";
/**
* Object identifier for the SHA-225 with ECDSA signature algorithm.
*/
public static final String OID_SHA224_WITH_ECDSA = "1.2.840.10045.4.3.1";
/**
* Object identifier for the SHA-256 with ECDSA signature algorithm.
*/
public static final String OID_SHA256_WITH_ECDSA = "1.2.840.10045.4.3.2";
/**
* Object identifier for the SHA-384 with ECDSA signature algorithm.
*/
public static final String OID_SHA384_WITH_ECDSA = "1.2.840.10045.4.3.3";
/**
* Object identifier for the SHA-512 with ECDSA signature algorithm.
*/
public static final String OID_SHA512_WITH_ECDSA = "1.2.840.10045.4.3.4";
// 1.2.840.113549.1
/**
* Object identifier for the MD2 with RSA signature algorithm.
*/
public static final String OID_MD2_WITH_RSA = "1.2.840.113549.1.1.2";
/**
* Object identifier for the MD4 with RSA signature algorithm.
*/
public static final String OID_MD4_WITH_RSA = "1.2.840.113549.1.1.3";
/**
* Object identifier for the MD5 with RSA signature algorithm.
*/
public static final String OID_MD5_WITH_RSA = "1.2.840.113549.1.1.4";
/**
* Object identifier for the SHA1 with RSA signature algorithm.
*/
public static final String OID_SHA1_WITH_RSA = "1.2.840.113549.1.1.5";
/**
* Object identifier for the SHA-256 with RSA signature algorithm.
*/
public static final String OID_SHA256_WITH_RSA = "1.2.840.113549.1.1.11";
/**
* Object identifier for the SHA-384 with RSA signature algorithm.
*/
public static final String OID_SHA384_WITH_RSA = "1.2.840.113549.1.1.12";
/**
* Object identifier for the SHA-512 with RSA signature algorithm.
*/
public static final String OID_SHA512_WITH_RSA = "1.2.840.113549.1.1.13";
/**
* Object identifier for the PKCS #9 {@code extensionRequest} attribute.
*
* @since 1.2.0
*/
public static final String OID_EXTENSION_REQUEST = "1.2.840.113549.1.9.14";
// 1.2.840.113549.2
/**
* Object identifier for the MD2 hash algorithm.
*/
public static final String OID_MD2 = "1.2.840.113549.2.2";
/**
* Object identifier for the MD5 hash algorithm.
*/
public static final String OID_MD5 = "1.2.840.113549.2.5";
// 1.3.14
/**
* Object identifier for the SHA1 hash algorithm.
*/
public static final String OID_SHA1 = "1.3.14.3.2.26";
/**
* Algorithm ID for RSA keys used for any purpose.
*/
public static final String OID_RSA = "1.2.840.113549.1.1.1";
/**
* Algorithm ID for DSA keys used for any purpose.
*/
public static final String OID_DSA = "1.2.840.10040.4.1";
/**
* Algorithm ID for EC keys used for any purpose.
*/
public static final String OID_EC = "1.2.840.10045.2.1";
/**
* Format an AS.1 string from the given decoder as a string.
*
* @param decoder the ASN.1 decoder
* @return the formatted string
*/
public static String formatAsn1(ASN1Decoder decoder) {
final StringBuilder builder = new StringBuilder();
formatAsn1(decoder, builder);
return builder.toString();
}
/**
* Format an ASN.1 string from the given decoder as a string.
*
* @param decoder the ASN.1 decoder
* @param builder the target string builder
*/
public static void formatAsn1(ASN1Decoder decoder, StringBuilder builder) {
while (decoder.hasNextElement()) {
final int type = decoder.peekType();
switch (type) {
case INTEGER_TYPE: {
builder.append("[int:").append(decoder.decodeInteger()).append("]");
break;
}
case BIT_STRING_TYPE: {
builder.append("[bits:").append(decoder.decodeBitStringAsString()).append(']');
break;
}
case OCTET_STRING_TYPE: {
builder.append("[octets:").append(Arrays2.toString(decoder.decodeOctetString())).append(']');
break;
}
case NULL_TYPE: {
builder.append("[null]");
decoder.decodeNull();
break;
}
case OBJECT_IDENTIFIER_TYPE: {
builder.append("[oid:").append(decoder.decodeObjectIdentifier()).append(']');
break;
}
case IA5_STRING_TYPE: {
builder.append("[ia5:").append(decoder.decodeIA5String()).append(']');
break;
}
case SEQUENCE_TYPE: {
builder.append("[sequence:");
decoder.startSequence();
formatAsn1(decoder, builder);
decoder.endSequence();
builder.append(']');
break;
}
case SET_TYPE: {
builder.append("[set:");
decoder.startSet();
formatAsn1(decoder, builder);
decoder.endSet();
builder.append(']');
break;
}
case PRINTABLE_STRING_TYPE: {
builder.append("[printable:").append(decoder.decodePrintableString()).append(']');
break;
}
case UNIVERSAL_STRING_TYPE: {
builder.append("[universal:").append(decoder.decodeUniversalString()).append(']');
break;
}
case UTF8_STRING_TYPE: {
builder.append("[utf8:").append(decoder.decodeUtf8String()).append(']');
break;
}
case BMP_STRING_TYPE: {
builder.append("[bmp:").append(decoder.decodeBMPString()).append(']');
break;
}
default: {
throw log.asnUnknownTagType(type);
}
}
}
}
/**
* Resolves a key algorithm based on a given oid
.
*
* @param oid an ASN.1 object identifier or OID (not {@code null})
* @return the string representing the key algorithm or null if no algorithm could be resolved for the given OID
*/
public static String keyAlgorithmFromOid(String oid) {
switch (oid) {
case OID_RSA:
return "RSA";
case OID_DSA:
return "DSA";
case OID_EC:
return "EC";
default:
return null;
}
}
@SuppressWarnings("SpellCheckingInspection")
public static String oidFromSignatureAlgorithm(String algorithmName) {
switch (algorithmName) {
case "NONEwithRSA": {
return null;
}
case "MD2withRSA": {
return OID_MD2_WITH_RSA;
}
case "MD5withRSA": {
return OID_MD5_WITH_RSA;
}
case "SHA1withRSA": {
return OID_SHA1_WITH_RSA;
}
case "SHA256withRSA": {
return OID_SHA256_WITH_RSA;
}
case "SHA384withRSA": {
return OID_SHA384_WITH_RSA;
}
case "SHA512withRSA": {
return OID_SHA512_WITH_RSA;
}
case "NONEwithDSA": {
return null;
}
case "SHA1withDSA": {
return OID_SHA1_WITH_DSA;
}
case "SHA256withDSA": {
return OID_SHA256_WITH_DSA;
}
case "NONEwithECDSA": {
return null;
}
case "ECDSA": // obsolete alias for SHA1withECDSA
case "SHA1withECDSA": {
return OID_SHA1_WITH_ECDSA;
}
case "SHA256withECDSA": {
return OID_SHA256_WITH_ECDSA;
}
case "SHA384withECDSA": {
return OID_SHA384_WITH_ECDSA;
}
case "SHA512withECDSA": {
return OID_SHA512_WITH_ECDSA;
}
default: {
return null;
}
}
}
@SuppressWarnings("SpellCheckingInspection")
public static String signatureAlgorithmFromOid(String oid) {
switch (oid) {
case OID_MD2_WITH_RSA: {
return "MD2withRSA";
}
case OID_MD5_WITH_RSA: {
return "MD5withRSA";
}
case OID_SHA1_WITH_RSA: {
return "SHA1withRSA";
}
case OID_SHA256_WITH_RSA: {
return "SHA256withRSA";
}
case OID_SHA384_WITH_RSA: {
return "SHA384withRSA";
}
case OID_SHA512_WITH_RSA: {
return "SHA512withRSA";
}
case OID_SHA1_WITH_DSA: {
return "SHA1withDSA";
}
case OID_SHA1_WITH_ECDSA: {
return "SHA1withECDSA";
}
case OID_SHA256_WITH_ECDSA: {
return "SHA256withECDSA";
}
case OID_SHA384_WITH_ECDSA: {
return "SHA384withECDSA";
}
case OID_SHA512_WITH_ECDSA: {
return "SHA512withECDSA";
}
default: {
return null;
}
}
}
public static void validatePrintableByte(final int b) throws ASN1Exception {
switch (b) {
case ' ':
case '\'':
case '(':
case ')':
case '+':
case ',':
case '-':
case '.':
case '/':
case ':':
case '=':
case '?': {
return;
}
default: {
if ('A' <= b && b <= 'Z' || 'a' <= b && b <= 'z' || '0' <= b && b <= '9') {
return;
}
throw log.asnUnexpectedCharacterByteForPrintableString();
}
}
}
}