| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.xml.security.utils; |
| |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.nio.file.Files; |
| import java.nio.file.Paths; |
| import java.security.SecurityPermission; |
| |
| /** |
| * A collection of different, general-purpose methods for JAVA-specific things |
| */ |
| public final class JavaUtils { |
| |
| private static final org.slf4j.Logger LOG = |
| org.slf4j.LoggerFactory.getLogger(JavaUtils.class); |
| |
| private static final SecurityPermission REGISTER_PERMISSION = |
| new SecurityPermission("org.apache.xml.security.register"); |
| |
| private JavaUtils() { |
| // we don't allow instantiation |
| } |
| |
| /** |
| * Method getBytesFromFile |
| * |
| * @param fileName |
| * @return the bytes read from the file |
| * |
| * @throws FileNotFoundException |
| * @throws IOException |
| */ |
| public static byte[] getBytesFromFile(String fileName) |
| throws FileNotFoundException, IOException { |
| |
| byte refBytes[] = null; |
| |
| try (InputStream inputStream = Files.newInputStream(Paths.get(fileName)); |
| UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream()) { |
| byte buf[] = new byte[1024]; |
| int len; |
| |
| while ((len = inputStream.read(buf)) > 0) { |
| baos.write(buf, 0, len); |
| } |
| |
| refBytes = baos.toByteArray(); |
| } |
| |
| return refBytes; |
| } |
| |
| /** |
| * Method writeBytesToFilename |
| * |
| * @param filename |
| * @param bytes |
| */ |
| public static void writeBytesToFilename(String filename, byte[] bytes) { |
| if (filename != null && bytes != null) { |
| try (OutputStream outputStream = Files.newOutputStream(Paths.get(filename))) { |
| outputStream.write(bytes); |
| } catch (IOException ex) { |
| LOG.debug(ex.getMessage(), ex); |
| } |
| } else { |
| LOG.debug("writeBytesToFilename got null byte[] pointed"); |
| } |
| } |
| |
| /** |
| * This method reads all bytes from the given InputStream till EOF and |
| * returns them as a byte array. |
| * |
| * @param inputStream |
| * @return the bytes read from the stream |
| * |
| * @throws FileNotFoundException |
| * @throws IOException |
| */ |
| public static byte[] getBytesFromStream(InputStream inputStream) throws IOException { |
| try (UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream()) { |
| byte buf[] = new byte[4 * 1024]; |
| int len; |
| while ((len = inputStream.read(buf)) > 0) { |
| baos.write(buf, 0, len); |
| } |
| return baos.toByteArray(); |
| } |
| } |
| |
| /** |
| * Converts an ASN.1 DSA value to a XML Signature DSA Value. |
| * |
| * The JCE DSA Signature algorithm creates ASN.1 encoded (r, s) value |
| * pairs (see section 2.2.2 of RFC 3279); the XML Signature requires the |
| * core BigInteger values. |
| * |
| * @param asn1Bytes the ASN.1 encoded bytes |
| * @param size size of r and s in bytes |
| * @return the XML Signature encoded bytes |
| * @throws IOException if the bytes are not encoded correctly |
| * @see <A HREF="http://www.w3.org/TR/xmldsig-core1/#sec-DSA">6.4.1 DSA</A> |
| */ |
| public static byte[] convertDsaASN1toXMLDSIG(byte[] asn1Bytes, int size) |
| throws IOException |
| { |
| if (asn1Bytes[0] != 48 || asn1Bytes[1] != asn1Bytes.length - 2 |
| || asn1Bytes[2] != 2) { |
| throw new IOException("Invalid ASN.1 format of DSA signature"); |
| } |
| |
| byte rLength = asn1Bytes[3]; |
| int i; |
| for (i = rLength; i > 0 && asn1Bytes[4 + rLength - i] == 0; i--); //NOPMD |
| |
| byte sLength = asn1Bytes[5 + rLength]; |
| int j; |
| for (j = sLength; j > 0 && asn1Bytes[6 + rLength + sLength - j] == 0; j--); //NOPMD |
| |
| if (i > size || asn1Bytes[4 + rLength] != 2 || j > size) { |
| throw new IOException("Invalid ASN.1 format of DSA signature"); |
| } else { |
| byte[] xmldsigBytes = new byte[size * 2]; |
| System.arraycopy(asn1Bytes, 4 + rLength - i, xmldsigBytes, |
| size - i, i); |
| System.arraycopy(asn1Bytes, 6 + rLength + sLength - j, |
| xmldsigBytes, size * 2 - j, j); |
| return xmldsigBytes; |
| } |
| } |
| |
| /** |
| * Converts an XML Signature DSA Value to a ASN.1 DSA value. |
| * |
| * The JCE DSA Signature algorithm creates ASN.1 encoded (r, s) value |
| * pairs (see section 2.2.2 of RFC 3279); the XML Signature requires the |
| * core BigInteger values. |
| * |
| * @param xmldsigBytes the XML Signature encoded bytes |
| * @param size size of r and s in bytes |
| * @return the ASN.1 encoded bytes |
| * @throws IOException if the bytes are not encoded correctly |
| * @see <A HREF="http://www.w3.org/TR/xmldsig-core1/#sec-DSA">6.4.1 DSA</A> |
| */ |
| public static byte[] convertDsaXMLDSIGtoASN1(byte[] xmldsigBytes, int size) |
| throws IOException |
| { |
| int totalSize = size * 2; |
| if (xmldsigBytes.length != totalSize) { |
| throw new IOException("Invalid XMLDSIG format of DSA signature"); |
| } |
| |
| int i; |
| for (i = size; i > 0 && xmldsigBytes[size - i] == 0; i--); //NOPMD |
| |
| int j = i; |
| if (xmldsigBytes[size - i] < 0) { |
| j++; |
| } |
| |
| int k; |
| for (k = size; k > 0 && xmldsigBytes[totalSize - k] == 0; k--); //NOPMD |
| |
| int l = k; |
| if (xmldsigBytes[totalSize - k] < 0) { |
| l++; |
| } |
| |
| byte[] asn1Bytes = new byte[6 + j + l]; |
| asn1Bytes[0] = 48; |
| asn1Bytes[1] = (byte)(4 + j + l); |
| asn1Bytes[2] = 2; |
| asn1Bytes[3] = (byte)j; |
| System.arraycopy(xmldsigBytes, size - i, asn1Bytes, 4 + j - i, i); |
| |
| asn1Bytes[4 + j] = 2; |
| asn1Bytes[5 + j] = (byte) l; |
| System.arraycopy(xmldsigBytes, totalSize - k, asn1Bytes, |
| 6 + j + l - k, k); |
| |
| return asn1Bytes; |
| } |
| |
| /** |
| * Throws a {@code SecurityException} if a security manager is installed |
| * and the caller is not allowed to register an implementation of an |
| * algorithm, transform, or other security sensitive XML Signature function. |
| * |
| * @throws SecurityException if a security manager is installed and the |
| * caller has not been granted the |
| * {@literal "org.apache.xml.security.register"} |
| * {@code SecurityPermission} |
| */ |
| public static void checkRegisterPermission() { |
| SecurityManager sm = System.getSecurityManager(); |
| if (sm != null) { |
| sm.checkPermission(REGISTER_PERMISSION); |
| } |
| } |
| } |