1fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro/*
2874c25b3bc5831e286885d08a60cf0f4c75d36dcPrzemyslaw Szczepaniak * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
3fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro *
5fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * This code is free software; you can redistribute it and/or modify it
6fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * under the terms of the GNU General Public License version 2 only, as
7fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * published by the Free Software Foundation.  Oracle designates this
8fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * particular file as subject to the "Classpath" exception as provided
9fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * by Oracle in the LICENSE file that accompanied this code.
10fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro *
11fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * This code is distributed in the hope that it will be useful, but WITHOUT
12fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * version 2 for more details (a copy is included in the LICENSE file that
15fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * accompanied this code).
16fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro *
17fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * You should have received a copy of the GNU General Public License version
18fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * 2 along with this work; if not, write to the Free Software Foundation,
19fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro *
21fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * or visit www.oracle.com if you need additional information or have any
23fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * questions.
24fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro */
25fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
26fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giropackage sun.security.util;
27fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
28fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giroimport java.security.AccessController;
29fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giroimport java.security.AlgorithmConstraints;
30fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giroimport java.security.PrivilegedAction;
31fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giroimport java.security.Security;
32fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giroimport java.util.Set;
33fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
34fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro/**
35fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro * The class contains common functionality for algorithm constraints classes.
36fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro */
37fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giropublic abstract class AbstractAlgorithmConstraints
38fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        implements AlgorithmConstraints {
39fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
40fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro    protected final AlgorithmDecomposer decomposer;
41fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
42fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro    protected AbstractAlgorithmConstraints(AlgorithmDecomposer decomposer) {
43fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        this.decomposer = decomposer;
44fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro    }
45fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
46fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro    // Get algorithm constraints from the specified security property.
47874c25b3bc5831e286885d08a60cf0f4c75d36dcPrzemyslaw Szczepaniak    static String[] getAlgorithms(String propertyName) {
48fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        String property = AccessController.doPrivileged(
4951e2670b94fbd372f45b7fdd4fec4505af3fd56cPrzemyslaw Szczepaniak                new PrivilegedAction<String>() {
5051e2670b94fbd372f45b7fdd4fec4505af3fd56cPrzemyslaw Szczepaniak                    @Override
5151e2670b94fbd372f45b7fdd4fec4505af3fd56cPrzemyslaw Szczepaniak                    public String run() {
5251e2670b94fbd372f45b7fdd4fec4505af3fd56cPrzemyslaw Szczepaniak                        return Security.getProperty(propertyName);
5351e2670b94fbd372f45b7fdd4fec4505af3fd56cPrzemyslaw Szczepaniak                    }
5451e2670b94fbd372f45b7fdd4fec4505af3fd56cPrzemyslaw Szczepaniak                });
5551e2670b94fbd372f45b7fdd4fec4505af3fd56cPrzemyslaw Szczepaniak
56fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
57fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        String[] algorithmsInProperty = null;
58fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        if (property != null && !property.isEmpty()) {
59fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            // remove double quote marks from beginning/end of the property
6044fa52b5119d3cd8c7e2fb934365d7e798b468b3Przemyslaw Szczepaniak            if (property.length() >= 2 && property.charAt(0) == '"' &&
6144fa52b5119d3cd8c7e2fb934365d7e798b468b3Przemyslaw Szczepaniak                    property.charAt(property.length() - 1) == '"') {
62fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro                property = property.substring(1, property.length() - 1);
63fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            }
64fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            algorithmsInProperty = property.split(",");
6544fa52b5119d3cd8c7e2fb934365d7e798b468b3Przemyslaw Szczepaniak            for (int i = 0; i < algorithmsInProperty.length; i++) {
66fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro                algorithmsInProperty[i] = algorithmsInProperty[i].trim();
67fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            }
68fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        }
69fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
70fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        // map the disabled algorithms
71fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        if (algorithmsInProperty == null) {
72fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            algorithmsInProperty = new String[0];
73fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        }
74874c25b3bc5831e286885d08a60cf0f4c75d36dcPrzemyslaw Szczepaniak        return algorithmsInProperty;
75fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro    }
76fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
77fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro    static boolean checkAlgorithm(String[] algorithms, String algorithm,
78fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            AlgorithmDecomposer decomposer) {
79fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        if (algorithm == null || algorithm.length() == 0) {
80fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            throw new IllegalArgumentException("No algorithm name specified");
81fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        }
82fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
83fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        Set<String> elements = null;
84fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        for (String item : algorithms) {
85fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            if (item == null || item.isEmpty()) {
86fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro                continue;
87fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            }
88fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
89fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            // check the full name
90fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            if (item.equalsIgnoreCase(algorithm)) {
91fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro                return false;
92fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            }
93fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
94fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            // decompose the algorithm into sub-elements
95fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            if (elements == null) {
96fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro                elements = decomposer.decompose(algorithm);
97fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            }
98fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
99fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            // check the items of the algorithm
100fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            for (String element : elements) {
101fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro                if (item.equalsIgnoreCase(element)) {
102fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro                    return false;
103fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro                }
104fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro            }
105fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        }
106fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
107fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro        return true;
108fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro    }
109fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro
110fb4c7d4fd77a0e37a3414b7199e0020c19acc5e5Sergio Giro}
111