2 * Copyright (C) 2007-2012 Argeo GmbH
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.argeo
.security
.crypto
;
18 import java
.security
.AccessController
;
22 import javax
.crypto
.SecretKey
;
23 import javax
.crypto
.SecretKeyFactory
;
24 import javax
.crypto
.spec
.PBEKeySpec
;
25 import javax
.crypto
.spec
.SecretKeySpec
;
26 import javax
.security
.auth
.Subject
;
27 import javax
.security
.auth
.callback
.Callback
;
28 import javax
.security
.auth
.callback
.CallbackHandler
;
29 import javax
.security
.auth
.callback
.PasswordCallback
;
30 import javax
.security
.auth
.login
.LoginException
;
31 import javax
.security
.auth
.spi
.LoginModule
;
33 /** Adds a secret key to the private credentials */
34 public class KeyringLoginModule
implements LoginModule
{
35 private Subject subject
;
36 private CallbackHandler callbackHandler
;
37 private SecretKey secretKey
;
39 public void initialize(Subject subject
, CallbackHandler callbackHandler
,
40 Map
<String
, ?
> sharedState
, Map
<String
, ?
> options
) {
41 this.subject
= subject
;
42 if (subject
== null) {
43 subject
= Subject
.getSubject(AccessController
.getContext());
45 this.callbackHandler
= callbackHandler
;
48 public boolean login() throws LoginException
{
49 Set
<SecretKey
> pbes
= subject
.getPrivateCredentials(SecretKey
.class);
52 PasswordCallback pc
= new PasswordCallback("Master password", false);
53 PBEKeySpecCallback pbeCb
= new PBEKeySpecCallback();
54 Callback
[] callbacks
= { pc
, pbeCb
};
56 callbackHandler
.handle(callbacks
);
57 char[] password
= pc
.getPassword();
59 SecretKeyFactory keyFac
= SecretKeyFactory
.getInstance(pbeCb
60 .getSecretKeyFactory());
62 if (pbeCb
.getKeyLength() != null)
63 keySpec
= new PBEKeySpec(password
, pbeCb
.getSalt(),
64 pbeCb
.getIterationCount(), pbeCb
.getKeyLength());
66 keySpec
= new PBEKeySpec(password
, pbeCb
.getSalt(),
67 pbeCb
.getIterationCount());
69 String secKeyEncryption
= pbeCb
.getSecretKeyEncryption();
70 if (secKeyEncryption
!= null) {
71 SecretKey tmp
= keyFac
.generateSecret(keySpec
);
72 secretKey
= new SecretKeySpec(tmp
.getEncoded(),
75 secretKey
= keyFac
.generateSecret(keySpec
);
77 } catch (Exception e
) {
78 LoginException le
= new LoginException("Cannot login keyring");
85 public boolean commit() throws LoginException
{
86 if (secretKey
!= null)
87 subject
.getPrivateCredentials().add(secretKey
);
91 public boolean abort() throws LoginException
{
95 public boolean logout() throws LoginException
{
96 Set
<PasswordBasedEncryption
> pbes
= subject
97 .getPrivateCredentials(PasswordBasedEncryption
.class);