Compare commits

...

11 Commits

Author SHA1 Message Date
c0de 819f4b736b update comment 2023-10-04 14:25:48 -05:00
c0de 141cf85eb7 Restructure README 2023-10-04 14:25:34 -05:00
c0de e9584d79b8 Reduce internal buffer size by 330 bytes
This sets the value to hold only rsa 2048 length (949) + 1 bytes
2023-10-04 13:47:21 -05:00
c0de 604de144c6 Choose better values for internal buffer max size
2048: 0x3B0 -> 0x3B6 (was actually 6 bytes too small)
3072: 0x570 -> 0x50F (was 61 bytes larger than necessary)
4096: 0x730 -> 0x66D (was 195 bytes larger than necessary)
2023-10-04 13:38:28 -05:00
c0de 1724975b08 Remove AUTHORS file
since we're preserving git history and copyright headers
2023-10-04 12:39:31 -05:00
c0de 41c367371f Rename License file 2023-10-04 12:33:16 -05:00
c0de 6925c1a366 update license headers to correct git repo 2023-10-04 12:21:18 -05:00
c0de 5168bb86d8 Enable Extended Length command chaining by default 2023-10-04 12:14:38 -05:00
c0de d70ca4b185 Remove factory reset patch
We do want the card to reset if the pin gets brute forced
2023-10-04 12:02:11 -05:00
c0de f14a76b2ae Remove demo videos 2023-10-04 11:45:24 -05:00
c0de f9593b4b41 Update Applet Class path 2023-10-04 11:45:05 -05:00
27 changed files with 109 additions and 164 deletions

View File

@ -3,6 +3,7 @@
# OpenPGPpy : Scan devices demo
# Copyright (C) 2020 BitLogiK
# Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
#
# 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

View File

@ -3,6 +3,7 @@
# OpenPGPpy : Reset device demo
# Copyright (C) 2020 BitLogiK
# Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
#
# 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

View File

@ -1,5 +1,5 @@
com.licel.jcardsim.card.applet.0.AID=d276000124010304AFAF000000000000
com.licel.jcardsim.card.applet.0.Class=fr.anssi.smartpgp.SmartPGPApplet
com.licel.jcardsim.card.applet.0.Class=dev.c0de.smartpgp.SmartPGPApplet
com.licel.jcardsim.card.ATR=3B80800101
com.licel.jcardsim.vsmartcard.host=localhost
com.licel.jcardsim.vsmartcard.port=35963

7
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"license.author": "Code Fox <SmartPGP@c0de.dev>",
"license.extension": ".txt",
"license.default": "GPL-2.0",
"license.filename": "LICENSE",
"license.year": "auto"
}

View File

@ -1,6 +0,0 @@
Maintainer: Arnaud Fontaine
Contributors:
- Arnaud Fontaine
- Pierre Chifflier (bin/*)

View File

@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
Copyright (C) <YEAR> <YOUR NAME> (<YOUR EMAIL ADDRESS>)
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

159
README.md
View File

@ -3,157 +3,116 @@
SmartPGP is a free and open source implementation of the [OpenPGP card
3.4 specification](https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.pdf) in JavaCard.
## Features
The following features are implemented at the applet level, but some
of them depend on underlying hardware support and available
(non-)volatile memory resources:
- RSA (>= 2048 bits modulus, 17 bits exponent) for signature,
encryption and authentication;
- On-board key generation and external private key import;
- PIN codes (user, admin and resetting code) up to 127 characters;
- Certificate up to 1 kB (DER encoded) for each key;
- Login, URL, and private DOs up to 256 bytes;
- Command and response chaining;
- AES 128/256 bits deciphering primitive;
- RSA (>= 2048 bits modulus, 17 bits exponent) for signature, encryption and authentication
- On-board key generation and external private key import
- PIN codes (user, admin and resetting code) up to 127 characters each
- Certificate up to 1 kB (DER encoded) for each key
- Login, URL, and private DOs up to 256 bytes
- Command and response chaining
- AES 128/256 bits deciphering primitive
## Default values
The SmartPGP applet is configured with the following default values:
- Admin PIN is 12345678;
- Admin PIN is 12345678
- User PIN is 123456
- No PUK (a.k.a. resetting code) is defined
- RSA 2048 bits for PGP keys
- User PIN is 123456;
These values can be changed by modifying the [Constants](src/dev/c0de/smartpgp/Constants.java) class.
- No PUK (a.k.a. resetting code) is defined;
After the applet has been installed, the [smartpgp-cli](bin/smartpgp-cli) utility
will be able to change the above values.
- RSA 2048 bits for PGP keys;
_Note: These settings are restored if you factory reset the applet._
These values can be changed by modifying default values in the code
(see the [Constants](src/fr/anssi/smartpgp/Constants.java)
class).
__Note: If you change algorithm attributes, the key and corresponding certificate will be erased.__
When the applet is installed, one can use the `smartpgp-cli` utility
given in the `bin` directory to change these values. Keep in mind that
when you change the algorithm attributes of a PGP key, the key and the
corresponding certificate are
erased. Also note that hard coded default values will be restored upon
a factory reset.
## Build and Install instructions
### Prerequisites
# Application support
Tokens following the OpenPGP card 3.4 specification are not yet fully
supported by most PGP applications.
## GnuPG
OpenPGP card 3.x is supported by [GnuPG](https://www.gnupg.org/)
starting from version 2.1.16.
## OpenKeychain
OpenPGP card 3.x is supported by [OpenKeychain](https://www.openkeychain.org/)
starting from version 4.2.
# Content of the repository
The repository contains several directories:
- `bin` contains a Python library and command line tool called
`smartpgp-cli` to interact with an OpenPGP card 3.x;
- `src` contains the JavaCard source code of the SmartPGP applet;
- `videos` contains sample videos demonstrating smartcard interactions
with OpenKeychain and K9 mail on Android Nexus 5.
# Build and installation instructions
## Prerequisites
- A Java compiler
- A device compliant with JavaCard 3.0.1 (or above) with enough
available resources to hold the code (approximately 23 kB of
non-volatile memory), persistent data (approximately 10 kB of
non-volatile memory) and volatile data (approximately 2 kB of RAM).
- A Java compiler (No higher than OpenJDK 11 or equivalent)
- A device compliant with JavaCard 3.0.1 (or above) with enough available resources
- Applet: ~23 KiB of non-volatile (eeprom/flash) memory
- Persistant Data: ~10 KiB of non-volatile (eeprom/flash) memory
- Transient Data: ~2 KiB of volatile (RAM) memory
<!-- - The [pyscard](https://pypi.org/project/pyscard/) and [pyasn1](https://pypi.org/project/pyasn1/)
Python libraries for `smartcard-cli`. -->
### Importing RSA keys above 2048 bits
## Importing RSA keys above 2048 bits (3072 or 4096 bits)
The internal buffer that stores keys is configured with a default value that is only large enough for RSA 2048 bit keys.
The size of the internal buffer is set by default to a value that
permits to import RSA 2048 bits. If your card is able to deal with RSA
keys of 3072 or 4096 bits and you want to be able to import such keys,
then you need to adjust the size of this buffer:
If your card is able to handle larger RSA key bit-lengths (3072 or 4096), and you want to import those keys, you will need to increase the buffer size.
- for RSA 2048 bits, `Constants.INTERNAL_BUFFER_MAX_LENGTH` must be at
least `(short)0x3b0`;
This can be accomplished by modifying `Constants.INTERNAL_BUFFER_MAX_LENGTH` in [Constants.java](src/dev/c0de/smartpgp/Constants.java)
- for RSA 3072 bits, `Constants.INTERNAL_BUFFER_MAX_LENGTH` must be at
least `(short)0x570`;
#### RSA 2048 bit keys
- for RSA 4096 bits, `Constants.INTERNAL_BUFFER_MAX_LENGTH` must be at
least `(short)0x730`.
When produced by OpenPGP, these keys are 949 Bytes in length.
`Constants.INTERNAL_BUFFER_MAX_LENGTH` may not be smaller than `(short)0x3b6` (decimal: 950)
#### RSA 3072 bit keys
## Reducing flash and/or RAM consumption
When produced by OpenPGP, these keys are 1294 Bytes in length.
`Constants.INTERNAL_BUFFER_MAX_LENGTH` may not be smaller than `(short)0x50f` (decimal: 1295)
The applet allocates all its data structures to their maximal size
at installation to avoid as much as possible runtime errors caused by
memory allocation failure. If your device does not have enough flash
and/or RAM available, or if you plan not to use some features
(e.g. stored certificates), you can adjust the applet to reduce its
resource consumption by tweaking the following variables:
#### RSA 4096 bit keys
When produced by OpenPGP, these keys are 1644 Bytes in length.
`Constants.INTERNAL_BUFFER_MAX_LENGTH` may not be smaller than `(short)0x66d` (decimal: 1645)
### Reducing flash and/or RAM consumption
When the applet is installed, all data structures will be allocated
to their maximum size. This is a standard practice for JavaCard applets
to ensure that there will not be a memory allocation failure at runtime.
A consequence of this is that, if you configure a large rsa key and
use a small key, that extra space can not be used for anything else.
If your device does not have enough flash memory and/or RAM, or you plan
to not use some features (eg. on-device certificates), you can modify
the following variables in [Constants.java](src/dev/c0de/smartpgp/Constants.java)
- `Constants.INTERNAL_BUFFER_MAX_LENGTH`: the size in bytes of the
internal RAM buffer used for input/output chaining. Chaining is
especially used in case of long commands and responses such as those
involved in private key import and certificate import/export;
- `Constants.EXTENDED_CAPABILITIES`, bytes 5 and 6: the maximal size
in bytes of a certificate associated to a key. Following the OpenPGP
card specification, a certificate can be stored for each of the
three keys.
- `Constants.EXTENDED_CAPABILITIES`, bytes 5 and 6: the maximum size
in bytes of a certificate associated to a key. The default is 1152 Bytes.
A certificate can be stored for each of the three keys.
## Building the CAP file
### Building the CAP file
- (Optional) Edit the `build.xml` file and replace the `APPLET_AID`
with your a unique value. Alternatively, set the
right AID instance bytes during applet installation.
Generate the AID using [this tool](https://c0de.dev/c0de/SmartPGP-AID-Generator)
- Execute `ant` with no parameter to build `SmartPGPApplet.cap`
- Execute `ant` to build `SmartPGPApplet.cap`
## Installing the CAP file
### Installing the CAP file
The CAP file installation depends on your device, so you have to refer
to the instructions given by your device manufacturer. Most open cards
relying on Global Platform with default keys are supported by
[GlobalPlatformPro](https://github.com/martinpaljak/GlobalPlatformPro).
Be careful to use a valid AID according to the OpenPGP card
specification (see section 4.2.1) for each card (`-create <AID>` with
GlobalPlatformPro)
You must use a valid, unique AID that matches the OpenPGP card specification (see section 4.2.1)
for each card (`-create <AID>` with GlobalPlatformPro)
Example Installation commands:
Example Installation commands:
- `gp --install SmartPGPApplet.cap --default`
- `gp --install SmartPGPApplet.cap --create <AID>`

View File

@ -1,8 +1,9 @@
#!/usr/bin/env python3
# SmartPGP : JavaCard implementation of OpenPGP card v3 specification
# https://github.com/ANSSI-FR/SmartPGP
# https://c0de.dev/c0de/SmartPGP
# Copyright (C) 2016 ANSSI
# Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License

View File

@ -1,6 +1,7 @@
# SmartPGP : JavaCard implementation of OpenPGP card v3 specification
# https://github.com/ANSSI-FR/SmartPGP
# https://c0de.dev/c0de/SmartPGP
# Copyright (C) 2016 ANSSI
# Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License

View File

@ -1,7 +1,8 @@
# SmartPGP : JavaCard implementation of OpenPGP card v3 specification
# https://github.com/ANSSI-FR/SmartPGP
# https://c0de.dev/c0de/SmartPGP
# Copyright (C) 2016 ANSSI
# Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License

View File

@ -11,7 +11,7 @@
<target name="convert">
<javacard>
<cap jckit="${JC303}" output="SmartPGPApplet.cap" sources="src" aid="d27600012401" version="1.0">
<applet class="fr.anssi.smartpgp.SmartPGPApplet" aid="d276000124010304c0deedb522560000"/>
<applet class="dev.c0de.smartpgp.SmartPGPApplet" aid="d276000124010304c0deedb522560000"/>
</cap>
</javacard>
</target>

View File

@ -1,17 +0,0 @@
diff --git a/src/fr/anssi/smartpgp/SmartPGPApplet.java b/src/fr/anssi/smartpgp/SmartPGPApplet.java
index c47870f..87162fb 100644
--- a/src/fr/anssi/smartpgp/SmartPGPApplet.java
+++ b/src/fr/anssi/smartpgp/SmartPGPApplet.java
@@ -1329,10 +1329,12 @@ public final class SmartPGPApplet extends Applet {
return;
}
+/*
if(data.admin_pin.getTriesRemaining() <= 0) {
data.isTerminated = true;
return;
}
+*/
assertAdmin();

View File

@ -1,13 +0,0 @@
diff --git a/src/fr/anssi/smartpgp/Constants.java b/src/fr/anssi/smartpgp/Constants.java
index b3c0f80..2ee1107 100644
--- a/src/fr/anssi/smartpgp/Constants.java
+++ b/src/fr/anssi/smartpgp/Constants.java
@@ -149,7 +149,7 @@ public final class Constants {
(byte)0x73, /* card capabilities */
(byte)0xC0, /* 1st byte: "methods supported" see ISO 7816-4 */
(byte)0x01, /* 2nd byte: "data coding byte" idem */
- (byte)0x80, /* 3rd byte: command chaining (not extended length by default as all readers do not support them...) */
+ (byte)0xC0, /* 3rd byte: command chaining + extended length */
(byte)0x05, /* status indicator byte : operational state */
(byte)0x90, /* SW1 */

View File

@ -1,7 +1,8 @@
/*
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
https://github.com/ANSSI-FR/SmartPGP
https://c0de.dev/c0de/SmartPGP
Copyright (C) 2016 ANSSI
Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -18,7 +19,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
import javacard.framework.*;
import javacard.security.*;

View File

@ -1,7 +1,8 @@
/*
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
https://github.com/ANSSI-FR/SmartPGP
https://c0de.dev/c0de/SmartPGP
Copyright (C) 2016 ANSSI
Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -18,14 +19,14 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
import javacard.framework.*;
public final class Constants {
protected static final short INTERNAL_BUFFER_MAX_LENGTH =
(short)0x500;
/* 0x3b6 for rsa 2048; 0x50f for rsa 3072; 0x66d for rsa 4096 */
protected static final short INTERNAL_BUFFER_MAX_LENGTH = (short)0x3b6; // Max size of key in bytes
protected static final short APDU_MAX_LENGTH = (short)0x400;
@ -148,7 +149,10 @@ public final class Constants {
(byte)0x73, /* card capabilities */
(byte)0xC0, /* 1st byte: "methods supported" see ISO 7816-4 */
(byte)0x01, /* 2nd byte: "data coding byte" idem */
(byte)0x80, /* 3rd byte: command chaining (not extended length by default as all readers do not support them...) */
/* 3rd byte: command chaining + extended length; Set to 0x80 if
extended length is not supported by card or reader */
(byte)0xC0,
(byte)0x05, /* status indicator byte : operational state */
(byte)0x90, /* SW1 */
@ -166,7 +170,7 @@ public final class Constants {
0x01), /* support KDF-DO */
(byte)0x00, /* SM 0x01 = 128 bits, 0x02 = 256 bits, 0x03 = SCP11b */
(byte)0x00, (byte)0x20, /* max length get challenge */
(byte)0x04, (byte)0x80, /* max length of carholder certificate */
(byte)0x04, (byte)0x80, /* max length of carholder certificate in Bytes (decimal: 1152) */
(byte)0x00, (byte)0xff, /* max length of special DOs (private, login, url, KDF-DO) */
(byte)0x00, /* PIN format 2 is not supported */
(byte)0x00 /* MSE not supported */

View File

@ -1,7 +1,8 @@
/*
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
https://github.com/ANSSI-FR/SmartPGP
https://c0de.dev/c0de/SmartPGP
Copyright (C) 2016 ANSSI
Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -18,7 +19,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
import javacard.framework.*;

View File

@ -1,7 +1,8 @@
/*
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
https://github.com/ANSSI-FR/SmartPGP
https://c0de.dev/c0de/SmartPGP
Copyright (C) 2016 ANSSI
Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -18,7 +19,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
import javacard.framework.*;
import javacard.security.*;

View File

@ -1,7 +1,8 @@
/*
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
https://github.com/ANSSI-FR/SmartPGP
https://c0de.dev/c0de/SmartPGP
Copyright (C) 2016 ANSSI
Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -18,7 +19,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
import javacard.framework.*;
import javacard.security.*;

View File

@ -1,7 +1,8 @@
/*
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
https://github.com/ANSSI-FR/SmartPGP
https://c0de.dev/c0de/SmartPGP
Copyright (C) 2016 ANSSI
Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -18,7 +19,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
import javacard.framework.*;
import javacard.security.*;

View File

@ -1,7 +1,8 @@
/*
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
https://github.com/ANSSI-FR/SmartPGP
https://c0de.dev/c0de/SmartPGP
Copyright (C) 2016 ANSSI
Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -18,7 +19,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
import javacard.framework.*;

View File

@ -6,7 +6,7 @@
<target name="convert">
<javacard>
<cap output="TestApplet.cap" sources="src" aid="aaaaaaaaaaaa" version="1.0">
<applet class="fr.anssi.smartpgp.TestApplet" aid="aaaaaaaaaaaa00000000000000000000"/>
<applet class="dev.c0de.smartpgp.TestApplet" aid="aaaaaaaaaaaa00000000000000000000"/>
</cap>
</javacard>
</target>

View File

@ -1,4 +1,4 @@
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
public final class Data {

View File

@ -1,4 +1,4 @@
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
public final class ECConstants {

View File

@ -1,4 +1,4 @@
package fr.anssi.smartpgp;
package dev.c0de.smartpgp;
import javacard.framework.*;

Binary file not shown.

Binary file not shown.

Binary file not shown.