001/**
002 * Copyright 2010-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.common.util.encrypt.openssl;
017
018import static org.kuali.common.util.base.Precondition.checkMin;
019import static org.kuali.common.util.base.Precondition.checkNotBlank;
020import static org.kuali.common.util.encrypt.EncryptionStrength.STRONG_ENCRYPTION_STRENGTH;
021
022import org.kuali.common.util.encrypt.EncryptionStrength;
023
024public final class OpenSSLContext {
025
026        private final int iterations;
027        private final String saltPrefix;
028        private final int saltSize;
029        private final int keySizeBits;
030        private final String transformation;
031        private final String digestAlgorithm;
032        private final String algorithm;
033
034        private OpenSSLContext(Builder builder) {
035                this.iterations = builder.iterations;
036                this.saltSize = builder.saltSize;
037                this.saltPrefix = builder.saltPrefix;
038                this.keySizeBits = builder.keySizeBits;
039                this.transformation = builder.transformation;
040                this.digestAlgorithm = builder.digestAlgorithm;
041                this.algorithm = builder.algorithm;
042        }
043
044        /**
045         * <p>
046         * <code>EncryptionStrength.STRONG_ENCRYPTION_STRENGTH</code> means AES 256, otherwise AES 128.
047         * <p>
048         * 
049         * <p>
050         * <strong>WARNING:</strong> AES 256 causes an exception to be thrown unless you've installed java's "unlimited strength jurisdiction policy files"
051         * </p>
052         */
053        public static OpenSSLContext buildOpenSSLContext(EncryptionStrength strength) {
054                if (STRONG_ENCRYPTION_STRENGTH.equals(strength)) {
055                        return builder().withKeySizeBits(Builder.STRONG_KEY_SIZE_BITS).build();
056                } else {
057                        return buildDefaultOpenSSLContext();
058                }
059        }
060
061        /**
062         * Returns a context for 128 bit AES encryption compatible with OpenSSL
063         */
064        public static OpenSSLContext buildDefaultOpenSSLContext() {
065                return builder().build();
066        }
067
068        public static Builder builder() {
069                return new Builder();
070        }
071
072        public static class Builder implements org.apache.commons.lang3.builder.Builder<OpenSSLContext> {
073
074                private static final int STRONG_KEY_SIZE_BITS = 256;
075
076                private int iterations = 1;
077                private String saltPrefix = "Salted__";
078                private int saltSize = 8;
079                private int keySizeBits = 128;
080                private String transformation = "AES/CBC/PKCS5Padding";
081                private String digestAlgorithm = "MD5";
082                private String algorithm = "AES";
083
084                private static OpenSSLContext validate(OpenSSLContext instance) {
085                        checkMin(instance.iterations, 0, "iterations");
086                        checkNotBlank(instance.saltPrefix, "saltPrefix");
087                        checkMin(instance.saltSize, 0, "saltSize");
088                        checkMin(instance.keySizeBits, 0, "keySizeBits");
089                        checkNotBlank(instance.transformation, "transformation");
090                        checkNotBlank(instance.digestAlgorithm, "digest");
091                        checkNotBlank(instance.algorithm, "algorithm");
092                        return instance;
093                }
094
095                @Override
096                public OpenSSLContext build() {
097                        return validate(new OpenSSLContext(this));
098                }
099
100                public Builder withAlgorithm(String algorithm) {
101                        this.algorithm = algorithm;
102                        return this;
103                }
104
105                public Builder withSaltPrefix(String saltPrefix) {
106                        this.saltPrefix = saltPrefix;
107                        return this;
108                }
109
110                public Builder withDigestAlgorithm(String digestAlgorithm) {
111                        this.digestAlgorithm = digestAlgorithm;
112                        return this;
113                }
114
115                public Builder withTransformation(String transformation) {
116                        this.transformation = transformation;
117                        return this;
118                }
119
120                public Builder withIterations(int iterations) {
121                        this.iterations = iterations;
122                        return this;
123                }
124
125                public Builder withSaltSize(int saltSize) {
126                        this.saltSize = saltSize;
127                        return this;
128                }
129
130                public Builder withKeySizeBits(int keySizeBits) {
131                        this.keySizeBits = keySizeBits;
132                        return this;
133                }
134
135                public int getIterations() {
136                        return iterations;
137                }
138
139                public void setIterations(int iterations) {
140                        this.iterations = iterations;
141                }
142
143                public String getSaltPrefix() {
144                        return saltPrefix;
145                }
146
147                public void setSaltPrefix(String saltPrefix) {
148                        this.saltPrefix = saltPrefix;
149                }
150
151                public int getSaltSize() {
152                        return saltSize;
153                }
154
155                public void setSaltSize(int saltSize) {
156                        this.saltSize = saltSize;
157                }
158
159                public int getKeySizeBits() {
160                        return keySizeBits;
161                }
162
163                public void setKeySizeBits(int keySizeBits) {
164                        this.keySizeBits = keySizeBits;
165                }
166
167                public String getTransformation() {
168                        return transformation;
169                }
170
171                public void setTransformation(String transformation) {
172                        this.transformation = transformation;
173                }
174
175                public String getDigestAlgorithm() {
176                        return digestAlgorithm;
177                }
178
179                public void setDigestAlgorithm(String digest) {
180                        this.digestAlgorithm = digest;
181                }
182
183                public String getAlgorithm() {
184                        return algorithm;
185                }
186
187                public void setAlgorithm(String algorithm) {
188                        this.algorithm = algorithm;
189                }
190        }
191
192        public int getIterations() {
193                return iterations;
194        }
195
196        public int getSaltSize() {
197                return saltSize;
198        }
199
200        public int getKeySizeBits() {
201                return keySizeBits;
202        }
203
204        public String getTransformation() {
205                return transformation;
206        }
207
208        public String getDigestAlgorithm() {
209                return digestAlgorithm;
210        }
211
212        public String getAlgorithm() {
213                return algorithm;
214        }
215
216        public String getSaltPrefix() {
217                return saltPrefix;
218        }
219}