Make graphics and resources folder lowercase
This commit is contained in:
BIN
resources/docs/openpgp_api_1.jpg
Normal file
BIN
resources/docs/openpgp_api_1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
BIN
resources/docs/passphrase1.png
Normal file
BIN
resources/docs/passphrase1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
BIN
resources/docs/passphrase2.png
Normal file
BIN
resources/docs/passphrase2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
BIN
resources/docs/passphrase3.png
Normal file
BIN
resources/docs/passphrase3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.service.remote;
|
||||
|
||||
interface IExtendedApiCallback {
|
||||
|
||||
oneway void onSuccess(in byte[] outputBytes);
|
||||
|
||||
oneway void onError(in String error);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.service.remote;
|
||||
|
||||
import org.sufficientlysecure.keychain.service.remote.IExtendedApiCallback;
|
||||
|
||||
/**
|
||||
* All methods are oneway, which means they are asynchronous and non-blocking.
|
||||
* Results are returned to the callback, which has to be implemented on client side.
|
||||
*/
|
||||
interface IExtendedApiService {
|
||||
|
||||
/**
|
||||
* Symmetric Encrypt
|
||||
*
|
||||
* @param inputBytes
|
||||
* Byte array you want to encrypt
|
||||
* @param passphrase
|
||||
* symmetric passhprase
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void encrypt(in byte[] inputBytes, in String passphrase, in IExtendedApiCallback callback);
|
||||
|
||||
/**
|
||||
* Generates self signed X509 certificate signed by OpenPGP private key (from app settings)
|
||||
*
|
||||
* @param subjAltNameURI
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void selfSignedX509Cert(in String subjAltNameURI, in IExtendedApiCallback callback);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.service.remote;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpToX509;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
|
||||
public class ExtendedApiService extends RemoteService {
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
private void selfSignedX509CertSafe(String subjAltNameURI, IExtendedApiCallback callback,
|
||||
AppSettings appSettings) {
|
||||
|
||||
// TODO: for pgp keyrings with password
|
||||
CallbackHandler pgpPwdCallbackHandler = new PgpToX509.PredefinedPasswordCallbackHandler("");
|
||||
|
||||
try {
|
||||
long keyId = appSettings.getKeyId();
|
||||
PGPSecretKey pgpSecretKey = PgpKeyHelper.getSigningKey(this, keyId);
|
||||
|
||||
PasswordCallback pgpSecKeyPasswordCallBack = new PasswordCallback("pgp passphrase?",
|
||||
false);
|
||||
pgpPwdCallbackHandler.handle(new Callback[] { pgpSecKeyPasswordCallBack });
|
||||
PGPPrivateKey pgpPrivKey = pgpSecretKey.extractPrivateKey(
|
||||
pgpSecKeyPasswordCallBack.getPassword(), Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||
pgpSecKeyPasswordCallBack.clearPassword();
|
||||
|
||||
X509Certificate selfSignedCert = PgpToX509.createSelfSignedCert(pgpSecretKey,
|
||||
pgpPrivKey, subjAltNameURI);
|
||||
|
||||
// Write x509cert and privKey into files
|
||||
// FileOutputStream fosCert = context.openFileOutput(CERT_FILENAME,
|
||||
// Context.MODE_PRIVATE);
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
PEMWriter pemWriterCert = new PEMWriter(new PrintWriter(outStream));
|
||||
pemWriterCert.writeObject(selfSignedCert);
|
||||
pemWriterCert.close();
|
||||
|
||||
byte[] outputBytes = outStream.toByteArray();
|
||||
|
||||
callback.onSuccess(outputBytes);
|
||||
} catch (Exception e) {
|
||||
Log.e(Constants.TAG, "ExtendedApiService", e);
|
||||
try {
|
||||
callback.onError(e.getMessage());
|
||||
} catch (RemoteException e1) {
|
||||
Log.e(Constants.TAG, "ExtendedApiService", e);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: no private key at the moment! Don't give it to others
|
||||
// PrivateKey privKey = pgpPrivKey.getKey();
|
||||
// FileOutputStream fosKey = context.openFileOutput(PRIV_KEY_FILENAME,
|
||||
// Context.MODE_PRIVATE);
|
||||
// PEMWriter pemWriterKey = new PEMWriter(new PrintWriter(fosKey));
|
||||
// pemWriterKey.writeObject(privKey);
|
||||
// pemWriterKey.close();
|
||||
}
|
||||
|
||||
private final IExtendedApiService.Stub mBinder = new IExtendedApiService.Stub() {
|
||||
|
||||
@Override
|
||||
public void encrypt(byte[] inputBytes, String passphrase, IExtendedApiCallback callback)
|
||||
throws RemoteException {
|
||||
// TODO : implement
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selfSignedX509Cert(final String subjAltNameURI,
|
||||
final IExtendedApiCallback callback) throws RemoteException {
|
||||
final AppSettings settings = getAppSettings();
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
selfSignedX509CertSafe(subjAltNameURI, callback, settings);
|
||||
}
|
||||
};
|
||||
|
||||
checkAndEnqueue(r);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
314
resources/old extended service/src/main/java/PgpToX509.java
Normal file
314
resources/old extended service/src/main/java/PgpToX509.java
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import org.bouncycastle.asn1.DERObjectIdentifier;
|
||||
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
|
||||
import org.bouncycastle.asn1.x509.BasicConstraints;
|
||||
import org.bouncycastle.asn1.x509.GeneralName;
|
||||
import org.bouncycastle.asn1.x509.GeneralNames;
|
||||
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
|
||||
import org.bouncycastle.asn1.x509.X509Extensions;
|
||||
import org.bouncycastle.asn1.x509.X509Name;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.x509.X509V3CertificateGenerator;
|
||||
import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
|
||||
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SignatureException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
|
||||
public class PgpToX509 {
|
||||
public static final String DN_COMMON_PART_O = "OpenPGP to X.509 Bridge";
|
||||
public static final String DN_COMMON_PART_OU = "OpenPGP Keychain cert";
|
||||
|
||||
/**
|
||||
* Creates a self-signed certificate from a public and private key. The (critical) key-usage
|
||||
* extension is set up with: digital signature, non-repudiation, key-encipherment, key-agreement
|
||||
* and certificate-signing. The (non-critical) Netscape extension is set up with: SSL client and
|
||||
* S/MIME. A URI subjectAltName may also be set up.
|
||||
*
|
||||
* @param pubKey public key
|
||||
* @param privKey private key
|
||||
* @param subject subject (and issuer) DN for this certificate, RFC 2253 format preferred.
|
||||
* @param startDate date from which the certificate will be valid (defaults to current date and time
|
||||
* if null)
|
||||
* @param endDate date until which the certificate will be valid (defaults to current date and time
|
||||
* if null) *
|
||||
* @param subjAltNameURI URI to be placed in subjectAltName
|
||||
* @return self-signed certificate
|
||||
* @throws InvalidKeyException
|
||||
* @throws SignatureException
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws IllegalStateException
|
||||
* @throws NoSuchProviderException
|
||||
* @throws CertificateException
|
||||
* @throws Exception
|
||||
* @author Bruno Harbulot
|
||||
*/
|
||||
public static X509Certificate createSelfSignedCert(
|
||||
PublicKey pubKey, PrivateKey privKey, X509Name subject, Date startDate, Date endDate,
|
||||
String subjAltNameURI)
|
||||
throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException,
|
||||
SignatureException, CertificateException, NoSuchProviderException {
|
||||
|
||||
X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
|
||||
|
||||
certGenerator.reset();
|
||||
/*
|
||||
* Sets up the subject distinguished name. Since it's a self-signed certificate, issuer and
|
||||
* subject are the same.
|
||||
*/
|
||||
certGenerator.setIssuerDN(subject);
|
||||
certGenerator.setSubjectDN(subject);
|
||||
|
||||
/*
|
||||
* Sets up the validity dates.
|
||||
*/
|
||||
if (startDate == null) {
|
||||
startDate = new Date(System.currentTimeMillis());
|
||||
}
|
||||
certGenerator.setNotBefore(startDate);
|
||||
if (endDate == null) {
|
||||
endDate = new Date(startDate.getTime() + (365L * 24L * 60L * 60L * 1000L));
|
||||
Log.d(Constants.TAG, "end date is=" + DateFormat.getDateInstance().format(endDate));
|
||||
}
|
||||
|
||||
certGenerator.setNotAfter(endDate);
|
||||
|
||||
/*
|
||||
* The serial-number of this certificate is 1. It makes sense because it's self-signed.
|
||||
*/
|
||||
certGenerator.setSerialNumber(BigInteger.ONE);
|
||||
/*
|
||||
* Sets the public-key to embed in this certificate.
|
||||
*/
|
||||
certGenerator.setPublicKey(pubKey);
|
||||
/*
|
||||
* Sets the signature algorithm.
|
||||
*/
|
||||
String pubKeyAlgorithm = pubKey.getAlgorithm();
|
||||
if (pubKeyAlgorithm.equals("DSA")) {
|
||||
certGenerator.setSignatureAlgorithm("SHA1WithDSA");
|
||||
} else if (pubKeyAlgorithm.equals("RSA")) {
|
||||
certGenerator.setSignatureAlgorithm("SHA1WithRSAEncryption");
|
||||
} else {
|
||||
RuntimeException re = new RuntimeException("Algorithm not recognised: "
|
||||
+ pubKeyAlgorithm);
|
||||
Log.e(Constants.TAG, re.getMessage(), re);
|
||||
throw re;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds the Basic Constraint (CA: true) extension.
|
||||
*/
|
||||
certGenerator.addExtension(X509Extensions.BasicConstraints, true,
|
||||
new BasicConstraints(true));
|
||||
|
||||
/*
|
||||
* Adds the subject key identifier extension.
|
||||
*/
|
||||
SubjectKeyIdentifier subjectKeyIdentifier = new SubjectKeyIdentifierStructure(pubKey);
|
||||
certGenerator
|
||||
.addExtension(X509Extensions.SubjectKeyIdentifier, false, subjectKeyIdentifier);
|
||||
|
||||
/*
|
||||
* Adds the authority key identifier extension.
|
||||
*/
|
||||
AuthorityKeyIdentifier authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(pubKey);
|
||||
certGenerator.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
|
||||
authorityKeyIdentifier);
|
||||
|
||||
/*
|
||||
* Adds the subject alternative-name extension.
|
||||
*/
|
||||
if (subjAltNameURI != null) {
|
||||
GeneralNames subjectAltNames = new GeneralNames(new GeneralName(
|
||||
GeneralName.uniformResourceIdentifier, subjAltNameURI));
|
||||
certGenerator.addExtension(X509Extensions.SubjectAlternativeName, false,
|
||||
subjectAltNames);
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates and sign this certificate with the private key corresponding to the public key of
|
||||
* the certificate (hence the name "self-signed certificate").
|
||||
*/
|
||||
X509Certificate cert = certGenerator.generate(privKey);
|
||||
|
||||
/*
|
||||
* Checks that this certificate has indeed been correctly signed.
|
||||
*/
|
||||
cert.verify(pubKey);
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a self-signed certificate from a PGP Secret Key.
|
||||
*
|
||||
* @param pgpSecKey PGP Secret Key (from which one can extract the public and private
|
||||
* keys and other attributes).
|
||||
* @param pgpPrivKey PGP Private Key corresponding to the Secret Key (password callbacks
|
||||
* should be done before calling this method)
|
||||
* @param subjAltNameURI optional URI to embed in the subject alternative-name
|
||||
* @return self-signed certificate
|
||||
* @throws PGPException
|
||||
* @throws NoSuchProviderException
|
||||
* @throws InvalidKeyException
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws SignatureException
|
||||
* @throws CertificateException
|
||||
* @author Bruno Harbulot
|
||||
*/
|
||||
public static X509Certificate createSelfSignedCert(
|
||||
PGPSecretKey pgpSecKey, PGPPrivateKey pgpPrivKey, String subjAltNameURI)
|
||||
throws PGPException, NoSuchProviderException, InvalidKeyException, NoSuchAlgorithmException,
|
||||
SignatureException, CertificateException {
|
||||
// get public key from secret key
|
||||
PGPPublicKey pgpPubKey = pgpSecKey.getPublicKey();
|
||||
|
||||
// LOGGER.info("Key ID: " + Long.toHexString(pgpPubKey.getKeyID() & 0xffffffffL));
|
||||
|
||||
/*
|
||||
* The X.509 Name to be the subject DN is prepared. The CN is extracted from the Secret Key
|
||||
* user ID.
|
||||
*/
|
||||
Vector<DERObjectIdentifier> x509NameOids = new Vector<DERObjectIdentifier>();
|
||||
Vector<String> x509NameValues = new Vector<String>();
|
||||
|
||||
x509NameOids.add(X509Name.O);
|
||||
x509NameValues.add(DN_COMMON_PART_O);
|
||||
|
||||
x509NameOids.add(X509Name.OU);
|
||||
x509NameValues.add(DN_COMMON_PART_OU);
|
||||
|
||||
for (@SuppressWarnings("unchecked")
|
||||
Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserIDs(); it.hasNext(); ) {
|
||||
Object attrib = it.next();
|
||||
x509NameOids.add(X509Name.CN);
|
||||
x509NameValues.add("CryptoCall");
|
||||
// x509NameValues.add(attrib.toString());
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently unused.
|
||||
*/
|
||||
Log.d(Constants.TAG, "User attributes: ");
|
||||
for (@SuppressWarnings("unchecked")
|
||||
Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserAttributes(); it.hasNext(); ) {
|
||||
Object attrib = it.next();
|
||||
Log.d(Constants.TAG, " - " + attrib + " -- " + attrib.getClass());
|
||||
}
|
||||
|
||||
X509Name x509name = new X509Name(x509NameOids, x509NameValues);
|
||||
|
||||
Log.d(Constants.TAG, "Subject DN: " + x509name);
|
||||
|
||||
/*
|
||||
* To check the signature from the certificate on the recipient side, the creation time
|
||||
* needs to be embedded in the certificate. It seems natural to make this creation time be
|
||||
* the "not-before" date of the X.509 certificate. Unlimited PGP keys have a validity of 0
|
||||
* second. In this case, the "not-after" date will be the same as the not-before date. This
|
||||
* is something that needs to be checked by the service receiving this certificate.
|
||||
*/
|
||||
Date creationTime = pgpPubKey.getCreationTime();
|
||||
Log.d(Constants.TAG,
|
||||
"pgp pub key creation time=" + DateFormat.getDateInstance().format(creationTime));
|
||||
Log.d(Constants.TAG, "pgp valid seconds=" + pgpPubKey.getValidSeconds());
|
||||
Date validTo = null;
|
||||
if (pgpPubKey.getValidSeconds() > 0) {
|
||||
validTo = new Date(creationTime.getTime() + 1000L * pgpPubKey.getValidSeconds());
|
||||
}
|
||||
|
||||
X509Certificate selfSignedCert = createSelfSignedCert(
|
||||
pgpPubKey.getKey(Constants.BOUNCY_CASTLE_PROVIDER_NAME), pgpPrivKey.getKey(),
|
||||
x509name, creationTime, validTo, subjAltNameURI);
|
||||
|
||||
return selfSignedCert;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a password callback handler that will fill in a password automatically. Useful to
|
||||
* configure passwords in advance, but should be used with caution depending on how much you
|
||||
* allow passwords to be stored within your application.
|
||||
*
|
||||
* @author Bruno Harbulot.
|
||||
*/
|
||||
public static final class PredefinedPasswordCallbackHandler implements CallbackHandler {
|
||||
|
||||
private char[] mPassword;
|
||||
private String mPrompt;
|
||||
|
||||
public PredefinedPasswordCallbackHandler(String password) {
|
||||
this(password == null ? null : password.toCharArray(), null);
|
||||
}
|
||||
|
||||
public PredefinedPasswordCallbackHandler(char[] password) {
|
||||
this(password, null);
|
||||
}
|
||||
|
||||
public PredefinedPasswordCallbackHandler(String password, String prompt) {
|
||||
this(password == null ? null : password.toCharArray(), prompt);
|
||||
}
|
||||
|
||||
public PredefinedPasswordCallbackHandler(char[] password, String prompt) {
|
||||
this.mPassword = password;
|
||||
this.mPrompt = prompt;
|
||||
}
|
||||
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
|
||||
for (Callback callback : callbacks) {
|
||||
if (callback instanceof PasswordCallback) {
|
||||
PasswordCallback pwCallback = (PasswordCallback) callback;
|
||||
if ((this.mPrompt == null) || (this.mPrompt.equals(pwCallback.getPrompt()))) {
|
||||
pwCallback.setPassword(this.mPassword);
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedCallbackException(callback, "Unrecognised callback.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected final Object clone() throws CloneNotSupportedException {
|
||||
throw new CloneNotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
25
resources/tools/android-wait-for-emulator
Executable file
25
resources/tools/android-wait-for-emulator
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Originally written by Ralf Kistner <ralf@embarkmobile.com>, but placed in the public domain
|
||||
|
||||
set +e
|
||||
|
||||
bootanim=""
|
||||
failcounter=0
|
||||
timeout_in_sec=720
|
||||
|
||||
until [[ "$bootanim" =~ "stopped" ]]; do
|
||||
bootanim=`adb -e shell getprop init.svc.bootanim 2>&1 &`
|
||||
if [[ "$bootanim" =~ "device not found" || "$bootanim" =~ "device offline"
|
||||
|| "$bootanim" =~ "running" ]]; then
|
||||
let "failcounter += 1"
|
||||
echo "Waiting for emulator to start"
|
||||
if [[ $failcounter -gt timeout_in_sec ]]; then
|
||||
echo "Timeout ($timeout_in_sec seconds) reached; failed to start emulator"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
|
||||
echo "Emulator is ready"
|
||||
1
resources/tools/checkstyle
Executable file
1
resources/tools/checkstyle
Executable file
@@ -0,0 +1 @@
|
||||
checkstyle -c tools/checkstyle.xml -r OpenKeychain/src/main/java 2>&1 | egrep -v 'log4j'
|
||||
362
resources/tools/checkstyle.xml
Normal file
362
resources/tools/checkstyle.xml
Normal file
@@ -0,0 +1,362 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!-- This is a checkstyle configuration file. For descriptions of
|
||||
what the following rules do, please see the checkstyle configuration
|
||||
page at http://checkstyle.sourceforge.net/config.html -->
|
||||
|
||||
<module name="OpenPgpChecker">
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="tools/suppressions.xml"/>
|
||||
</module>
|
||||
<module name="RegexpSingleline">
|
||||
<!-- Requires a copyright notice in each file.
|
||||
Code intended to be open-sourced may have a multi-line copyright
|
||||
notice, so that this required text appears on the second line:
|
||||
<pre>
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* (details of open-source license...)
|
||||
</pre>
|
||||
-->
|
||||
<property name="format"
|
||||
value="^(//| \*) Copyright (\([cC]\) )?[\d]{4}(\-[\d]{4})? .*$"/>
|
||||
<property name="minimum" value="1"/>
|
||||
<property name="maximum" value="10"/>
|
||||
<property name="message" value="Copyright is missing or malformed."/>
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="^import.*\*.*$"/>
|
||||
<property name="message" value="Wildcard imports are not ideal."/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="FileTabCharacter">
|
||||
<!-- Checks that there are no tab characters in the file.
|
||||
-->
|
||||
</module>
|
||||
|
||||
<module name="NewlineAtEndOfFile">
|
||||
<property name="lineSeparator" value="lf"/>
|
||||
</module>
|
||||
|
||||
<module name="RegexpSingleline">
|
||||
<!-- Checks that FIXME is not used in comments. TODO is preferred.
|
||||
-->
|
||||
<property name="format" value="((//.*)|(\*.*))FIXME"/>
|
||||
<property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."'/>
|
||||
</module>
|
||||
|
||||
<!--
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="((//.*)|(\*.*))TODO[^(]"/>
|
||||
<property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."'/>
|
||||
</module>
|
||||
-->
|
||||
|
||||
<!-- All Java AST specific tests live under TreeWalker module. -->
|
||||
<module name="TreeWalker">
|
||||
|
||||
<!--
|
||||
|
||||
IMPORT CHECKS
|
||||
|
||||
-->
|
||||
|
||||
<module name="RedundantImport">
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
<module name="UnusedImports">
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
<module name="ImportOrder">
|
||||
<!-- Checks for out of order import statements. -->
|
||||
|
||||
<property name="severity" value="warning"/>
|
||||
<property name="groups" value="com.google,android,junit,com,net,org,se,java,javax"/>
|
||||
<!-- This ensures that static imports go first. -->
|
||||
<property name="option" value="top"/>
|
||||
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
|
||||
</module>
|
||||
|
||||
<!--
|
||||
|
||||
JAVADOC CHECKS
|
||||
|
||||
-->
|
||||
|
||||
<!-- Checks for Javadoc comments. -->
|
||||
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
|
||||
<!--
|
||||
<module name="JavadocMethod">
|
||||
<property name="scope" value="protected"/>
|
||||
<property name="severity" value="warning"/>
|
||||
<property name="allowMissingJavadoc" value="true"/>
|
||||
<property name="allowMissingParamTags" value="true"/>
|
||||
<property name="allowMissingReturnTag" value="true"/>
|
||||
<property name="allowMissingThrowsTags" value="true"/>
|
||||
<property name="allowThrowsTagsForSubclasses" value="true"/>
|
||||
<property name="allowUndeclaredRTE" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="JavadocType">
|
||||
<property name="scope" value="protected"/>
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
<module name="JavadocStyle">
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
-->
|
||||
|
||||
<!--
|
||||
|
||||
NAMING CHECKS
|
||||
|
||||
-->
|
||||
|
||||
<!-- Item 38 - Adhere to generally accepted naming conventions -->
|
||||
|
||||
<module name="PackageName">
|
||||
<!-- Validates identifiers for package names against the
|
||||
supplied expression. -->
|
||||
<!-- Here the default checkstyle rule restricts package name parts to
|
||||
seven characters, this is not in line with common practice at Google.
|
||||
-->
|
||||
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="TypeNameCheck">
|
||||
<!-- Validates static, final fields against the
|
||||
expression "^[A-Z][a-zA-Z0-9]*$". -->
|
||||
<metadata name="altname" value="TypeName"/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="ConstantNameCheck">
|
||||
<!-- Validates non-private, static, final fields against the supplied
|
||||
public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
|
||||
<metadata name="altname" value="ConstantName"/>
|
||||
<property name="applyToPublic" value="true"/>
|
||||
<property name="applyToProtected" value="true"/>
|
||||
<property name="applyToPackage" value="true"/>
|
||||
<property name="applyToPrivate" value="false"/>
|
||||
<property name="format" value="^([A-Z_][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="StaticVariableNameCheck">
|
||||
<!-- Validates static, non-final fields against the supplied
|
||||
expression "^[a-z][a-zA-Z0-9]*_?$". -->
|
||||
<metadata name="altname" value="StaticVariableName"/>
|
||||
<property name="applyToPublic" value="true"/>
|
||||
<property name="applyToProtected" value="true"/>
|
||||
<property name="applyToPackage" value="true"/>
|
||||
<property name="applyToPrivate" value="true"/>
|
||||
<property name="format" value="^s[A-Z][a-zA-Z0-9]*_?$"/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="MemberNameCheck">
|
||||
<!-- Validates non-static members against the supplied expression. -->
|
||||
<metadata name="altname" value="MemberName"/>
|
||||
<property name="applyToPublic" value="false"/>
|
||||
<property name="applyToProtected" value="true"/>
|
||||
<property name="applyToPackage" value="true"/>
|
||||
<property name="applyToPrivate" value="true"/>
|
||||
<property name="format" value="^m[A-Z][a-zA-Z0-9]*$"/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="MemberNameCheck">
|
||||
<!-- Validates non-static members against the supplied expression. -->
|
||||
<metadata name="altname" value="MemberName"/>
|
||||
<property name="applyToPublic" value="true"/>
|
||||
<property name="applyToProtected" value="false"/>
|
||||
<property name="applyToPackage" value="false"/>
|
||||
<property name="applyToPrivate" value="false"/>
|
||||
<property name="format" value="^[a-z]([^A-Z]|$)[a-zA-Z0-9]*$"/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="MethodNameCheck">
|
||||
<!-- Validates identifiers for method names. -->
|
||||
<metadata name="altname" value="MethodName"/>
|
||||
<property name="format" value="^[a-z]([^A-Z]|$)[a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="ParameterName">
|
||||
<!-- Validates identifiers for method parameters against the
|
||||
expression "^[a-z][a-zA-Z0-9]*$". -->
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="LocalFinalVariableName">
|
||||
<!-- Validates identifiers for local final variables against the
|
||||
expression "^[a-z][a-zA-Z0-9]*$". -->
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="LocalVariableName">
|
||||
<!-- Validates identifiers for local variables against the
|
||||
expression "^[a-z][a-zA-Z0-9]*$". -->
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
LENGTH and CODING CHECKS
|
||||
|
||||
-->
|
||||
|
||||
<module name="LineLength">
|
||||
<!-- Checks if a line is too long. -->
|
||||
<property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="110"/>
|
||||
<property name="severity" value="error"/>
|
||||
|
||||
<!--
|
||||
The default ignore pattern exempts the following elements:
|
||||
- import statements
|
||||
- long URLs inside comments
|
||||
-->
|
||||
|
||||
<property name="ignorePattern"
|
||||
value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
|
||||
default="^(package .*;\s*)|(import .*;\s*)|( *\* *https?://.*)$"/>
|
||||
</module>
|
||||
|
||||
<module name="LeftCurly">
|
||||
<!-- Checks for placement of the left curly brace ('{'). -->
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="RightCurly">
|
||||
<!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
|
||||
the same line. e.g., the following example is fine:
|
||||
<pre>
|
||||
if {
|
||||
...
|
||||
} else
|
||||
</pre>
|
||||
-->
|
||||
<!-- This next example is not fine:
|
||||
<pre>
|
||||
if {
|
||||
...
|
||||
}
|
||||
else
|
||||
</pre>
|
||||
-->
|
||||
<property name="option" value="same"/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for braces around if and else blocks -->
|
||||
<module name="NeedBraces">
|
||||
<property name="severity" value="warning"/>
|
||||
<property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
|
||||
</module>
|
||||
|
||||
<module name="UpperEll">
|
||||
<!-- Checks that long constants are defined with an upper ell.-->
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
<module name="FallThrough">
|
||||
<!-- Warn about falling through to the next case statement. Similar to
|
||||
javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
|
||||
on the last non-blank line preceding the fallen-into case contains 'fall through' (or
|
||||
some other variants which we don't publicized to promote consistency).
|
||||
-->
|
||||
<property name="reliefPattern"
|
||||
value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
MODIFIERS CHECKS
|
||||
|
||||
-->
|
||||
|
||||
<module name="ModifierOrder">
|
||||
<!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
|
||||
8.4.3. The prescribed order is:
|
||||
public, protected, private, abstract, static, final, transient, volatile,
|
||||
synchronized, native, strictfp
|
||||
-->
|
||||
</module>
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
WHITESPACE CHECKS
|
||||
|
||||
-->
|
||||
|
||||
<module name="WhitespaceAround">
|
||||
<!-- Checks that various tokens are surrounded by whitespace.
|
||||
This includes most binary operators and keywords followed
|
||||
by regular or curly braces.
|
||||
-->
|
||||
<property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
|
||||
BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
|
||||
EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
|
||||
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
|
||||
LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
|
||||
MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
|
||||
SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
<module name="WhitespaceAfter">
|
||||
<!-- Checks that commas, semicolons and typecasts are followed by
|
||||
whitespace.
|
||||
-->
|
||||
<property name="tokens" value="COMMA, SEMI, TYPECAST"/>
|
||||
</module>
|
||||
|
||||
<module name="NoWhitespaceAfter">
|
||||
<!-- Checks that there is no whitespace after various unary operators.
|
||||
Linebreaks are allowed.
|
||||
-->
|
||||
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
|
||||
UNARY_PLUS"/>
|
||||
<property name="allowLineBreaks" value="true"/>
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
<module name="NoWhitespaceBefore">
|
||||
<!-- Checks that there is no whitespace before various unary operators.
|
||||
Linebreaks are allowed.
|
||||
-->
|
||||
<property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
|
||||
<property name="allowLineBreaks" value="true"/>
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
<module name="ParenPad">
|
||||
<!-- Checks that there is no whitespace before close parens or after
|
||||
open parens.
|
||||
-->
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
</module>
|
||||
|
||||
13
resources/tools/reset_yubikey.txt
Normal file
13
resources/tools/reset_yubikey.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
/hex
|
||||
scd serialno
|
||||
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 e6 00 00
|
||||
scd apdu 00 44 00 00
|
||||
/echo Card has been successfully reset.
|
||||
11
resources/tools/suppressions.xml
Normal file
11
resources/tools/suppressions.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
|
||||
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
|
||||
|
||||
<suppressions>
|
||||
<suppress files="(Constants|Id|R|PgpConversionHelper)\.java" checks=".*NameCheck"/>
|
||||
<suppress files="FileDialog.java" checks="StaticVariableNameCheck"/>
|
||||
<suppress files="PRNGFixes.java" checks=".*"/>
|
||||
</suppressions>
|
||||
Reference in New Issue
Block a user