Initial commit
This commit is contained in:
233
src/fr/anssi/smartpgp/Persistent.java
Normal file
233
src/fr/anssi/smartpgp/Persistent.java
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
|
||||
https://github.com/ANSSI-FR/smartpgp
|
||||
Copyright (C) 2016 ANSSI
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package fr.anssi.smartpgp;
|
||||
|
||||
import javacard.framework.*;
|
||||
import javacard.security.*;
|
||||
import javacardx.apdu.*;
|
||||
import javacardx.crypto.*;
|
||||
|
||||
public final class Persistent {
|
||||
|
||||
protected boolean isTerminated;
|
||||
|
||||
protected final byte[] login;
|
||||
protected short login_length;
|
||||
|
||||
protected final byte[] url;
|
||||
protected short url_length;
|
||||
|
||||
protected final PGPKey[] pgp_keys;
|
||||
protected static final byte PGP_KEYS_OFFSET_SIG = 0;
|
||||
protected static final byte PGP_KEYS_OFFSET_DEC = PGP_KEYS_OFFSET_SIG + 1;
|
||||
protected static final byte PGP_KEYS_OFFSET_AUT = PGP_KEYS_OFFSET_DEC + 1;
|
||||
private static final byte PGP_KEYS_LENGTH = PGP_KEYS_OFFSET_AUT + 1;
|
||||
|
||||
protected final Fingerprint[] fingerprints;
|
||||
protected static final byte FINGERPRINTS_OFFSET_CA = 0;
|
||||
protected static final byte FINGERPRINTS_OFFSET_CB = FINGERPRINTS_OFFSET_CA + 1;
|
||||
protected static final byte FINGERPRINTS_OFFSET_CC = FINGERPRINTS_OFFSET_CB + 1;
|
||||
private static final byte FINGERPRINTS_LENGTH = FINGERPRINTS_OFFSET_CC + 1;
|
||||
|
||||
protected final byte[] name;
|
||||
protected byte name_length;
|
||||
|
||||
protected final byte[] lang;
|
||||
protected byte lang_length;
|
||||
|
||||
protected byte sex;
|
||||
|
||||
|
||||
protected byte[] digital_signature_counter;
|
||||
|
||||
|
||||
protected byte[] do_0101;
|
||||
protected short do_0101_length;
|
||||
|
||||
protected byte[] do_0102;
|
||||
protected short do_0102_length;
|
||||
|
||||
protected byte[] do_0103;
|
||||
protected short do_0103_length;
|
||||
|
||||
protected byte[] do_0104;
|
||||
protected short do_0104_length;
|
||||
|
||||
protected AESKey aes_key;
|
||||
|
||||
|
||||
|
||||
protected final OwnerPIN user_pin; /* PW1 */
|
||||
protected byte user_pin_length;
|
||||
protected boolean user_pin_force_verify_signature;
|
||||
|
||||
protected final OwnerPIN user_puk; /* resetting code */
|
||||
protected byte user_puk_length;
|
||||
|
||||
protected final OwnerPIN admin_pin; /* PW3 */
|
||||
protected byte admin_pin_length;
|
||||
|
||||
|
||||
|
||||
protected Persistent() {
|
||||
login = new byte[Constants.specialDoMaxLength()];
|
||||
login_length = 0;
|
||||
|
||||
url = new byte[Constants.specialDoMaxLength()];
|
||||
url_length = 0;
|
||||
|
||||
fingerprints = new Fingerprint[FINGERPRINTS_LENGTH];
|
||||
for(byte i = 0; i < fingerprints.length; ++i) {
|
||||
fingerprints[i] = new Fingerprint();
|
||||
}
|
||||
|
||||
name = new byte[Constants.NAME_MAX_LENGTH];
|
||||
name_length = 0;
|
||||
|
||||
lang = new byte[Constants.LANG_MAX_LENGTH];
|
||||
lang_length = 0;
|
||||
|
||||
digital_signature_counter = new byte[3];
|
||||
|
||||
do_0101 = new byte[Constants.specialDoMaxLength()];
|
||||
do_0101_length = 0;
|
||||
|
||||
do_0102 = new byte[Constants.specialDoMaxLength()];
|
||||
do_0101_length = 0;
|
||||
|
||||
do_0103 = new byte[Constants.specialDoMaxLength()];
|
||||
do_0103_length = 0;
|
||||
|
||||
do_0104 = new byte[Constants.specialDoMaxLength()];
|
||||
do_0104_length = 0;
|
||||
|
||||
aes_key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
|
||||
(short)(Constants.aesKeyLength() * 8),
|
||||
false);
|
||||
|
||||
pgp_keys = new PGPKey[PGP_KEYS_LENGTH];
|
||||
for(byte i = 0; i < pgp_keys.length; ++i) {
|
||||
pgp_keys[i] = new PGPKey(false);
|
||||
}
|
||||
|
||||
user_pin = new OwnerPIN(Constants.USER_PIN_RETRY_COUNT, Constants.USER_PIN_MAX_SIZE);
|
||||
user_puk = new OwnerPIN(Constants.USER_PUK_RETRY_COUNT, Constants.USER_PUK_MAX_SIZE);
|
||||
admin_pin = new OwnerPIN(Constants.ADMIN_PIN_RETRY_COUNT, Constants.ADMIN_PIN_MAX_SIZE);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
protected void reset() {
|
||||
for(byte i = 0; i < pgp_keys.length; ++i) {
|
||||
pgp_keys[i].reset();
|
||||
}
|
||||
|
||||
if(login_length > 0) {
|
||||
JCSystem.beginTransaction();
|
||||
Util.arrayFillNonAtomic(login, (short)0, login_length, (byte)0);
|
||||
login_length = (short)0;
|
||||
JCSystem.commitTransaction();
|
||||
}
|
||||
|
||||
if(url_length > 0) {
|
||||
JCSystem.beginTransaction();
|
||||
Util.arrayFillNonAtomic(url, (short)0, url_length, (byte)0);
|
||||
url_length = (short)0;
|
||||
JCSystem.commitTransaction();
|
||||
}
|
||||
|
||||
for(byte i = 0; i < fingerprints.length; ++i) {
|
||||
fingerprints[i].reset();
|
||||
}
|
||||
|
||||
if(name_length > 0) {
|
||||
JCSystem.beginTransaction();
|
||||
Util.arrayFillNonAtomic(name, (short)0, name_length, (byte)0);
|
||||
name_length = (byte)0;
|
||||
JCSystem.commitTransaction();
|
||||
}
|
||||
|
||||
JCSystem.beginTransaction();
|
||||
if(lang_length > 0) {
|
||||
Util.arrayFillNonAtomic(lang, (short)0, lang_length, (byte)0);
|
||||
}
|
||||
Util.arrayCopyNonAtomic(Constants.LANG_DEFAULT, (short)0, lang, (short)0, (short)Constants.LANG_DEFAULT.length);
|
||||
lang_length = (byte)Constants.LANG_DEFAULT.length;
|
||||
JCSystem.commitTransaction();
|
||||
|
||||
sex = Constants.SEX_NOT_ANNOUNCED;
|
||||
|
||||
Util.arrayFillNonAtomic(digital_signature_counter, (short)0,
|
||||
(short)digital_signature_counter.length, (byte)0);
|
||||
|
||||
JCSystem.beginTransaction();
|
||||
if(do_0101_length > 0) {
|
||||
Util.arrayFillNonAtomic(do_0101, (short)0,
|
||||
(short)do_0101.length, (byte)0);
|
||||
do_0101_length = 0;
|
||||
}
|
||||
JCSystem.commitTransaction();
|
||||
|
||||
JCSystem.beginTransaction();
|
||||
if(do_0102_length > 0) {
|
||||
Util.arrayFillNonAtomic(do_0102, (short)0,
|
||||
(short)do_0102.length, (byte)0);
|
||||
do_0102_length = 0;
|
||||
}
|
||||
JCSystem.commitTransaction();
|
||||
|
||||
JCSystem.beginTransaction();
|
||||
if(do_0103_length > 0) {
|
||||
Util.arrayFillNonAtomic(do_0103, (short)0,
|
||||
(short)do_0103.length, (byte)0);
|
||||
do_0103_length = 0;
|
||||
}
|
||||
JCSystem.commitTransaction();
|
||||
|
||||
JCSystem.beginTransaction();
|
||||
if(do_0104_length > 0) {
|
||||
Util.arrayFillNonAtomic(do_0104, (short)0,
|
||||
(short)do_0104.length, (byte)0);
|
||||
do_0104_length = 0;
|
||||
}
|
||||
JCSystem.commitTransaction();
|
||||
|
||||
aes_key.clearKey();
|
||||
|
||||
user_pin_force_verify_signature = Constants.USER_PIN_DEFAULT_FORCE_VERIFY_SIGNATURE;
|
||||
|
||||
JCSystem.beginTransaction();
|
||||
user_pin_length = (byte)Constants.USER_PIN_DEFAULT.length;
|
||||
user_pin.update(Constants.USER_PIN_DEFAULT, (short)0, user_pin_length);
|
||||
user_pin.resetAndUnblock();
|
||||
JCSystem.commitTransaction();
|
||||
|
||||
user_puk_length = 0;
|
||||
|
||||
JCSystem.beginTransaction();
|
||||
admin_pin_length = (byte)Constants.ADMIN_PIN_DEFAULT.length;
|
||||
admin_pin.update(Constants.ADMIN_PIN_DEFAULT, (short)0, admin_pin_length);
|
||||
admin_pin.resetAndUnblock();
|
||||
JCSystem.commitTransaction();
|
||||
|
||||
isTerminated = false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user