001: /*
002: * Copyright 2007 The Kuali Foundation
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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: */
016: package edu.iu.uis.eden.security;
017:
018: import java.io.File;
019: import java.io.FileInputStream;
020: import java.io.IOException;
021: import java.security.GeneralSecurityException;
022: import java.security.KeyException;
023: import java.security.KeyStore;
024: import java.security.PrivateKey;
025: import java.security.PublicKey;
026: import java.security.Signature;
027: import java.security.cert.Certificate;
028:
029: import org.apache.commons.lang.StringUtils;
030: import org.kuali.rice.config.Config;
031: import org.kuali.rice.core.Core;
032: import org.springframework.beans.factory.InitializingBean;
033:
034: public class DigitalSignatureServiceImpl implements
035: DigitalSignatureService, InitializingBean {
036:
037: private static final String SHA_RSA_ALGORITHM = "SHA1withRSA";
038: private static final String JKS_TYPE = "JKS";
039:
040: private String keyStoreLocation;
041: private String keyStoreAlias;
042: private String keyStorePassword;
043:
044: private KeyStore keyStore;
045: private PrivateKey privateKey;
046:
047: /**
048: * Load the keystore and private key for this "application"
049: */
050: public void afterPropertiesSet() throws Exception {
051: if (StringUtils.isEmpty(this .keyStoreLocation)) {
052: setKeyStoreLocation(Core.getCurrentContextConfig()
053: .getKeystoreFile());
054: }
055: if (StringUtils.isEmpty(this .keyStoreAlias)) {
056: setKeyStoreAlias(Core.getCurrentContextConfig()
057: .getKeystoreAlias());
058: }
059: if (StringUtils.isEmpty(this .keyStorePassword)) {
060: setKeyStorePassword(Core.getCurrentContextConfig()
061: .getKeystorePassword());
062: }
063: verifyConfiguration();
064: this .keyStore = loadKeyStore();
065: this .privateKey = loadPrivateKey();
066: }
067:
068: /**
069: * Verifies the configuration of this service and throws an exception if it is not configured properly.
070: */
071: protected void verifyConfiguration() {
072: if (StringUtils.isEmpty(getKeyStoreLocation())) {
073: throw new RuntimeException(
074: "Value for configuration parameter '"
075: + Config.KEYSTORE_FILE
076: + "' could not be found. Please ensure that the keystore is configured properly.");
077: }
078: if (StringUtils.isEmpty(getKeyStoreAlias())) {
079: throw new RuntimeException(
080: "Value for configuration parameter '"
081: + Config.KEYSTORE_ALIAS
082: + "' could not be found. Please ensure that the keystore is configured properly.");
083: }
084: if (StringUtils.isEmpty(getKeyStorePassword())) {
085: throw new RuntimeException(
086: "Value for configuration parameter '"
087: + Config.KEYSTORE_PASSWORD
088: + "' could not be found. Please ensure that the keystore is configured properly.");
089: }
090: File keystoreFile = new File(getKeyStoreLocation());
091: if (!keystoreFile.exists()) {
092: throw new RuntimeException(
093: "Value for configuration parameter '"
094: + Config.KEYSTORE_FILE
095: + "' is invalid. The file does not exist on the filesystem, location was: '"
096: + getKeyStoreLocation() + "'");
097: }
098: if (!keystoreFile.canRead()) {
099: throw new RuntimeException(
100: "Value for configuration parameter '"
101: + Config.KEYSTORE_FILE
102: + "' is invalid. The file exists but is not readable (please check permissions), location was: '"
103: + getKeyStoreLocation() + "'");
104: }
105: }
106:
107: public Signature getSignatureForSigning() throws IOException,
108: GeneralSecurityException {
109: Signature signature = getSignature();
110: signature.initSign(this .privateKey);
111: return signature;
112: }
113:
114: public Signature getSignatureForVerification(
115: String verificationAlias) throws IOException,
116: GeneralSecurityException {
117: Signature signature = getSignature();
118: PublicKey publicKey = getPublicKey(verificationAlias);
119: if (publicKey == null) {
120: throw new KeyException(
121: "Could not find the public key for the given alias: "
122: + verificationAlias + " in keystore "
123: + getKeyStoreLocation());
124: }
125: signature.initVerify(publicKey);
126: return signature;
127: }
128:
129: public void setKeyStoreAlias(String keyStoreAlias) {
130: this .keyStoreAlias = keyStoreAlias;
131: }
132:
133: public void setKeyStoreLocation(String keyStoreLocation) {
134: this .keyStoreLocation = keyStoreLocation;
135: }
136:
137: public void setKeyStorePassword(String keyStorePassword) {
138: this .keyStorePassword = keyStorePassword;
139: }
140:
141: protected Signature getSignature() throws GeneralSecurityException {
142: return Signature.getInstance(getAlgorithm());
143: }
144:
145: protected KeyStore loadKeyStore() throws GeneralSecurityException,
146: IOException {
147: KeyStore keyStore = KeyStore.getInstance(getKeyStoreType());
148: keyStore.load(new FileInputStream(getKeyStoreLocation()),
149: getKeyStorePassword().toCharArray());
150: return keyStore;
151: }
152:
153: protected PrivateKey loadPrivateKey()
154: throws GeneralSecurityException {
155: return (PrivateKey) this .keyStore.getKey(getKeyStoreAlias(),
156: getKeyStorePassword().toCharArray());
157: }
158:
159: protected PublicKey getPublicKey(String alias)
160: throws GeneralSecurityException {
161: Certificate cert = this .keyStore.getCertificate(alias);
162: if (cert == null) {
163: return null;
164: }
165: return cert.getPublicKey();
166: }
167:
168: protected String getKeyStoreType() {
169: return JKS_TYPE;
170: }
171:
172: protected String getAlgorithm() {
173: return SHA_RSA_ALGORITHM;
174: }
175:
176: protected String getKeyStoreLocation() {
177: return this .keyStoreLocation;
178: }
179:
180: public String getKeyStoreAlias() {
181: return this .keyStoreAlias;
182: }
183:
184: protected String getKeyStorePassword() {
185: return this .keyStorePassword;
186: }
187:
188: protected KeyStore getKeyStore() {
189: return this.keyStore;
190: }
191:
192: }
|