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
.cms
.auth
;
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 import org
.argeo
.cms
.security
.PasswordBasedEncryption
;
34 import org
.argeo
.node
.security
.PBEKeySpecCallback
;
36 /** Adds a secret key to the private credentials */
37 public class KeyringLoginModule
implements LoginModule
{
38 private Subject subject
;
39 private CallbackHandler callbackHandler
;
40 private SecretKey secretKey
;
42 public void initialize(Subject subject
, CallbackHandler callbackHandler
,
43 Map
<String
, ?
> sharedState
, Map
<String
, ?
> options
) {
44 this.subject
= subject
;
45 if (subject
== null) {
46 subject
= Subject
.getSubject(AccessController
.getContext());
48 this.callbackHandler
= callbackHandler
;
51 public boolean login() throws LoginException
{
52 Set
<SecretKey
> pbes
= subject
.getPrivateCredentials(SecretKey
.class);
55 PasswordCallback pc
= new PasswordCallback("Master password", false);
56 PBEKeySpecCallback pbeCb
= new PBEKeySpecCallback();
57 Callback
[] callbacks
= { pc
, pbeCb
};
59 callbackHandler
.handle(callbacks
);
60 char[] password
= pc
.getPassword();
62 SecretKeyFactory keyFac
= SecretKeyFactory
.getInstance(pbeCb
63 .getSecretKeyFactory());
65 if (pbeCb
.getKeyLength() != null)
66 keySpec
= new PBEKeySpec(password
, pbeCb
.getSalt(),
67 pbeCb
.getIterationCount(), pbeCb
.getKeyLength());
69 keySpec
= new PBEKeySpec(password
, pbeCb
.getSalt(),
70 pbeCb
.getIterationCount());
72 String secKeyEncryption
= pbeCb
.getSecretKeyEncryption();
73 if (secKeyEncryption
!= null) {
74 SecretKey tmp
= keyFac
.generateSecret(keySpec
);
75 secretKey
= new SecretKeySpec(tmp
.getEncoded(),
78 secretKey
= keyFac
.generateSecret(keySpec
);
80 } catch (Exception e
) {
81 LoginException le
= new LoginException("Cannot login keyring");
88 public boolean commit() throws LoginException
{
89 if (secretKey
!= null)
90 subject
.getPrivateCredentials().add(secretKey
);
94 public boolean abort() throws LoginException
{
98 public boolean logout() throws LoginException
{
99 Set
<PasswordBasedEncryption
> pbes
= subject
100 .getPrivateCredentials(PasswordBasedEncryption
.class);