1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23 package com.sun.org.apache.xml.internal.security.utils; 24 25 import java.io.FileNotFoundException; 26 import java.io.IOException; 27 import java.io.InputStream; 28 import java.io.OutputStream; 29 import java.nio.file.Files; 30 import java.nio.file.Paths; 31 import java.security.SecurityPermission; 32 33 /** 34 * A collection of different, general-purpose methods for JAVA-specific things 35 */ 36 public final class JavaUtils { 37 38 private static final com.sun.org.slf4j.internal.Logger LOG = 39 com.sun.org.slf4j.internal.LoggerFactory.getLogger(JavaUtils.class); 40 41 private static final SecurityPermission REGISTER_PERMISSION = 42 new SecurityPermission("com.sun.org.apache.xml.internal.security.register"); 43 JavaUtils()44 private JavaUtils() { 45 // we don't allow instantiation 46 } 47 48 /** 49 * Method getBytesFromFile 50 * 51 * @param fileName 52 * @return the bytes read from the file 53 * 54 * @throws FileNotFoundException 55 * @throws IOException 56 */ getBytesFromFile(String fileName)57 public static byte[] getBytesFromFile(String fileName) 58 throws FileNotFoundException, IOException { 59 60 byte refBytes[] = null; 61 62 try (InputStream inputStream = Files.newInputStream(Paths.get(fileName)); 63 UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream()) { 64 byte buf[] = new byte[1024]; 65 int len; 66 67 while ((len = inputStream.read(buf)) > 0) { 68 baos.write(buf, 0, len); 69 } 70 71 refBytes = baos.toByteArray(); 72 } 73 74 return refBytes; 75 } 76 77 /** 78 * Method writeBytesToFilename 79 * 80 * @param filename 81 * @param bytes 82 */ writeBytesToFilename(String filename, byte[] bytes)83 public static void writeBytesToFilename(String filename, byte[] bytes) { 84 if (filename != null && bytes != null) { 85 try (OutputStream outputStream = Files.newOutputStream(Paths.get(filename))) { 86 outputStream.write(bytes); 87 } catch (IOException ex) { 88 LOG.debug(ex.getMessage(), ex); 89 } 90 } else { 91 LOG.debug("writeBytesToFilename got null byte[] pointed"); 92 } 93 } 94 95 /** 96 * This method reads all bytes from the given InputStream till EOF and 97 * returns them as a byte array. 98 * 99 * @param inputStream 100 * @return the bytes read from the stream 101 * 102 * @throws FileNotFoundException 103 * @throws IOException 104 */ getBytesFromStream(InputStream inputStream)105 public static byte[] getBytesFromStream(InputStream inputStream) throws IOException { 106 try (UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream()) { 107 byte buf[] = new byte[4 * 1024]; 108 int len; 109 while ((len = inputStream.read(buf)) > 0) { 110 baos.write(buf, 0, len); 111 } 112 return baos.toByteArray(); 113 } 114 } 115 116 /** 117 * Converts an ASN.1 DSA value to a XML Signature DSA Value. 118 * 119 * The JCE DSA Signature algorithm creates ASN.1 encoded (r, s) value 120 * pairs (see section 2.2.2 of RFC 3279); the XML Signature requires the 121 * core BigInteger values. 122 * 123 * @param asn1Bytes the ASN.1 encoded bytes 124 * @param size size of r and s in bytes 125 * @return the XML Signature encoded bytes 126 * @throws IOException if the bytes are not encoded correctly 127 * @see <A HREF="http://www.w3.org/TR/xmldsig-core1/#sec-DSA">6.4.1 DSA</A> 128 */ convertDsaASN1toXMLDSIG(byte[] asn1Bytes, int size)129 public static byte[] convertDsaASN1toXMLDSIG(byte[] asn1Bytes, int size) 130 throws IOException 131 { 132 if (asn1Bytes[0] != 48 || asn1Bytes[1] != asn1Bytes.length - 2 133 || asn1Bytes[2] != 2) { 134 throw new IOException("Invalid ASN.1 format of DSA signature"); 135 } 136 137 byte rLength = asn1Bytes[3]; 138 int i; 139 for (i = rLength; i > 0 && asn1Bytes[4 + rLength - i] == 0; i--); //NOPMD 140 141 byte sLength = asn1Bytes[5 + rLength]; 142 int j; 143 for (j = sLength; j > 0 && asn1Bytes[6 + rLength + sLength - j] == 0; j--); //NOPMD 144 145 if (i > size || asn1Bytes[4 + rLength] != 2 || j > size) { 146 throw new IOException("Invalid ASN.1 format of DSA signature"); 147 } else { 148 byte[] xmldsigBytes = new byte[size * 2]; 149 System.arraycopy(asn1Bytes, 4 + rLength - i, xmldsigBytes, 150 size - i, i); 151 System.arraycopy(asn1Bytes, 6 + rLength + sLength - j, 152 xmldsigBytes, size * 2 - j, j); 153 return xmldsigBytes; 154 } 155 } 156 157 /** 158 * Converts an XML Signature DSA Value to a ASN.1 DSA value. 159 * 160 * The JCE DSA Signature algorithm creates ASN.1 encoded (r, s) value 161 * pairs (see section 2.2.2 of RFC 3279); the XML Signature requires the 162 * core BigInteger values. 163 * 164 * @param xmldsigBytes the XML Signature encoded bytes 165 * @param size size of r and s in bytes 166 * @return the ASN.1 encoded bytes 167 * @throws IOException if the bytes are not encoded correctly 168 * @see <A HREF="http://www.w3.org/TR/xmldsig-core1/#sec-DSA">6.4.1 DSA</A> 169 */ convertDsaXMLDSIGtoASN1(byte[] xmldsigBytes, int size)170 public static byte[] convertDsaXMLDSIGtoASN1(byte[] xmldsigBytes, int size) 171 throws IOException 172 { 173 int totalSize = size * 2; 174 if (xmldsigBytes.length != totalSize) { 175 throw new IOException("Invalid XMLDSIG format of DSA signature"); 176 } 177 178 int i; 179 for (i = size; i > 0 && xmldsigBytes[size - i] == 0; i--); //NOPMD 180 181 int j = i; 182 if (xmldsigBytes[size - i] < 0) { 183 j++; 184 } 185 186 int k; 187 for (k = size; k > 0 && xmldsigBytes[totalSize - k] == 0; k--); //NOPMD 188 189 int l = k; 190 if (xmldsigBytes[totalSize - k] < 0) { 191 l++; 192 } 193 194 byte[] asn1Bytes = new byte[6 + j + l]; 195 asn1Bytes[0] = 48; 196 asn1Bytes[1] = (byte)(4 + j + l); 197 asn1Bytes[2] = 2; 198 asn1Bytes[3] = (byte)j; 199 System.arraycopy(xmldsigBytes, size - i, asn1Bytes, 4 + j - i, i); 200 201 asn1Bytes[4 + j] = 2; 202 asn1Bytes[5 + j] = (byte) l; 203 System.arraycopy(xmldsigBytes, totalSize - k, asn1Bytes, 204 6 + j + l - k, k); 205 206 return asn1Bytes; 207 } 208 209 /** 210 * Throws a {@code SecurityException} if a security manager is installed 211 * and the caller is not allowed to register an implementation of an 212 * algorithm, transform, or other security sensitive XML Signature function. 213 * 214 * @throws SecurityException if a security manager is installed and the 215 * caller has not been granted the 216 * {@literal "com.sun.org.apache.xml.internal.security.register"} 217 * {@code SecurityPermission} 218 */ checkRegisterPermission()219 public static void checkRegisterPermission() { 220 SecurityManager sm = System.getSecurityManager(); 221 if (sm != null) { 222 sm.checkPermission(REGISTER_PERMISSION); 223 } 224 } 225 } 226