Skip to content

Commit 03870cc

Browse files
committed
Working version pipeline
1 parent 201c388 commit 03870cc

File tree

4 files changed

+62
-16
lines changed

4 files changed

+62
-16
lines changed

.drone.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ clone:
88
workspace:
99
path: /app/src
1010

11+
volumes:
12+
- name: cache
13+
temp:
14+
medium: memory
15+
1116
steps:
1217
- name: clone
1318
image: alpine/git
@@ -18,10 +23,16 @@ steps:
1823
image: stargate01/smartcard-ci
1924
commands:
2025
- /app/src/scripts/compile-all.sh
26+
volumes:
27+
- name: cache
28+
path: /tmp
2129
- name: test
2230
image: stargate01/smartcard-ci
2331
commands:
2432
- /app/src/scripts/test-all.sh
33+
volumes:
34+
- name: cache
35+
path: /tmp
2536
- name: publish
2637
image: plugins/github-release
2738
settings:

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ Public compiled binaries are available from the GitHub releases page: https://gi
1515
## Development Usage
1616

1717
Install Docker. Use the `docker-*.sh` scripts in `scripts/` to compile and test the applets. Binaries will be placed in `bin/`. This repository also runs on a Drone CI server.
18+
19+
## Version Command
20+
21+
The build system in this repository adds an extra version APDU command to each applet. See `scripts/compile/res/version.py`. Use this build system if you want to generate release equivalent binaries.

scripts/compile/res/compile.sh

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@ prepare_build() {
1010
}
1111

1212
patch_version() {
13-
git config --global --add safe.directory /app/src
14-
cd /app/src
15-
TAG=`git tag --points-at HEAD`
1613
SRC="$BUILD/build.xml"
1714
if [ ! -f $SRC ]; then
1815
SRC="$BUILD/build.gradle"
1916
fi
20-
/app/src/scripts/compile/res/version.py -s $SRC -p $1 -v $TAG
17+
/app/src/scripts/compile/res/version.py -s $SRC -p $1 -v $DRONE_TAG
2118
}
2219

2320
build_default() {

scripts/compile/res/version.py

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,68 @@
1212
parser.add_argument('-v', '--version', nargs='?', dest='version', type=str,
1313
const='255.255.255', default='255.255.255', help='Build version to encode')
1414
args = parser.parse_args()
15-
1615
version = args.version.strip('v')
17-
18-
print('Patching file ' + args.patch + ' using the applet version from ' + args.source + ' and the additional build version ' + version)
16+
print('info: Patching file: ' + args.patch)
17+
print('info: Applet version from: ' + args.source)
18+
print('info: Additional build version: ' + version)
1919

20+
# Parse version source file
21+
_, ext = os.path.splitext(args.source)
2022
if(not os.path.isfile(args.source)):
2123
print('error: source file ' + args.source + 'does not exist')
2224
exit(1)
23-
24-
# Parse version source file
25-
_, ext = os.path.splitext(args.source)
2625
with open(args.source, 'r') as f:
2726
config = f.read()
2827
if(ext == '.xml'):
2928
# Ant XML file
30-
matches = re.findall("cap.*version[\s='\"]*([^\s'\"]*)", config, flags=re.DOTALL)
29+
matches = re.search("cap.*version[\s='\"]*([^\s'\"]*)", config, flags=re.DOTALL)
3130
elif(ext == '.gradle'):
3231
# Gradle config
33-
matches = re.findall("javacard {.*version[\s=']*([^\s']*)", config, flags=re.DOTALL)
32+
matches = re.search("javacard {.*version[\s=']*([^\s']*)", config, flags=re.DOTALL)
3433
else:
3534
print('error: Unknown source file format: ' + ext)
36-
37-
if(len(matches) == 0):
35+
if(matches == None):
3836
print("error: Cannot find version in config file")
3937
exit(1)
40-
appversion = matches[0]
41-
print("info: Found source version: " + appversion)
38+
appversion = matches.group(1)
39+
print("info: Found applet version: " + appversion)
40+
41+
# Generate patch
42+
appversion = appversion.split('.')
43+
version = version.split('.')
44+
patch = '''
45+
byte[] ver_buf = apdu.getBuffer();
46+
if(ver_buf[ISO7816.OFFSET_INS] == (byte) 0xF4 && ver_buf[ISO7816.OFFSET_P1] == (byte) 0x99 && ver_buf[ISO7816.OFFSET_P2] == (byte) 0x99) {{
47+
short ver_le = apdu.setOutgoing();
48+
short ver_len = (short) 5;
49+
ver_len = ver_le > (short) 0 ? (ver_le > ver_len ? ver_len : ver_le) : ver_len;
50+
ver_buf[0] = (byte) {};
51+
ver_buf[1] = (byte) {};
52+
ver_buf[2] = (byte) {};
53+
ver_buf[3] = (byte) {};
54+
ver_buf[4] = (byte) {};
55+
apdu.setOutgoingLength(ver_len);
56+
apdu.sendBytes((short) 0, ver_len);
57+
ver_buf = null;
58+
return;
59+
}} else {{
60+
ver_buf = null;
61+
}}
62+
'''.format(appversion[0], appversion[1], version[0], version[1], version[2])
4263

64+
# Find patch location and apply patch
4365
if(not os.path.isfile(args.patch)):
4466
print('error: patch file ' + args.patch + 'does not exist')
4567
exit(1)
68+
with open(args.patch, 'r') as f:
69+
patchtarget = f.read()
70+
match = re.search("void\s*process\s*\((?:final)?\s*APDU apdu\)\s*(?:throws ISOException)?\s*{", patchtarget, flags=re.DOTALL)
71+
if(match == None):
72+
print("error: Cannot find process method in patch file")
73+
exit(1)
74+
offset = match.end()
75+
patchtarget = patchtarget[:offset] + patch + patchtarget[offset:]
76+
with open(args.patch, 'w') as f:
77+
f.write(patchtarget)
78+
79+
print("info: Done patching")

0 commit comments

Comments
 (0)