111 Commits

Author SHA1 Message Date
20143bdf9b bump version 2025-11-24 23:00:42 +01:00
cc03bab86c no tests 2025-11-24 22:47:00 +01:00
64b4a94f26 add git 2025-11-24 22:35:34 +01:00
85abd0e6f2 built w/o binaries 2025-11-24 22:33:38 +01:00
867f61bcc9 try glibc 2025-11-24 22:30:29 +01:00
918db22bff markdown 2025-11-24 22:20:37 +01:00
2f0216496d fix libbsd 2025-11-24 22:08:47 +01:00
7f5158ae20 again 2025-11-24 22:07:02 +01:00
b6938c10ab fix sodium apk 2025-11-24 22:05:20 +01:00
28693971ef also migrate tests to meson 2025-11-24 22:01:44 +01:00
fdfbdb7061 move to meson and ninja: build of lib and binary 2025-11-24 13:44:53 +01:00
Thomas von Dein
48e87fd605 merge z85 bugfix#903 from https://github.com/zeromq/libzmq/pull/2322 2017-08-23 13:01:35 +02:00
Thomas von Dein
7e54d27011 version bump to 0.4.1 2017-08-23 13:00:12 +02:00
Thomas von Dein
5e726d6b69 using direkt buffer_add() in pcp_export_json_pub() as well 2016-10-26 08:24:05 +02:00
Thomas von Dein
5255a076db fixed off-by-one bug in buffer_add_str() 2016-10-26 08:23:34 +02:00
Thomas von Dein
56f35a66d8 regen 2016-10-26 08:23:16 +02:00
Thomas von Dein
3f7410c1e3 added hints about installing jansson and python stuff 2016-10-26 06:53:55 +02:00
Thomas von Dein
652c60e546 re-generated 2016-10-26 06:53:42 +02:00
Thomas von Dein
b999baf858 added hints about installing jansson and python stuff 2016-10-26 06:50:27 +02:00
Thomas von Dein
5b9b0c3dca added unittests, now that perl isnt involved anymore 2016-10-26 06:49:57 +02:00
Thomas von Dein
e1e0a3e53c removed perl stuff, not needed anymore 2016-10-26 06:49:30 +02:00
Thomas von Dein
7663df792d not required anymore 2016-10-26 06:39:54 +02:00
Thomas von Dein
48947064bf fixed missing free() errors 2016-10-25 22:07:08 +02:00
Thomas von Dein
918fa997f9 rm 2016-10-25 21:33:28 +02:00
Thomas von Dein
9c78f3ad63 last perl tests migrated to unittests.sh 2016-10-25 21:33:16 +02:00
Thomas von Dein
2cb91c93e0 move from unittest perl tp shell script, more portable and easier to understand 2016-10-25 16:33:12 +02:00
Thomas von Dein
0b1e843ee8 fix segfault bug if given vault is NULL 2016-10-25 16:32:05 +02:00
Thomas von Dein
7672be2a8d forgot to add writing of keysigs after deletions 2016-10-25 16:31:29 +02:00
Thomas von Dein
55ac156754 forgot to add writing of keysigs after deletions 2016-10-25 16:31:12 +02:00
Thomas von Dein
753d5bb51f regenerated 2016-10-25 16:30:42 +02:00
Thomas von Dein
e0ef92cb29 regen 2016-10-25 13:19:01 +02:00
Thomas von Dein
ceca615fef catch missing input 2016-10-25 13:18:24 +02:00
Thomas von Dein
c68c1626a6 wrong call 2016-10-25 13:18:11 +02:00
Thomas von Dein
a997a9fe55 added missing header(freebsd) 2016-10-25 11:29:53 +02:00
Thomas von Dein
f182c64796 regen 2016-10-21 10:23:01 +02:00
Thomas von Dein
0af5822abd added keysig to checksum calculation 2016-10-21 10:19:41 +02:00
Thomas von Dein
f657cfa703 better sig2blob and back wrappers 2016-10-21 10:19:17 +02:00
Thomas von Dein
cb654bd48f del unused funcs, rename blob2sig 2016-10-21 10:04:46 +02:00
Thomas von Dein
b8008d1207 removed endian conversion code, now we just write in big-endian on output with shifts, not swaps etc 2016-10-20 23:14:14 +02:00
Thomas von Dein
f664cc24c4 bump 2016-10-20 23:12:00 +02:00
Thomas von Dein
94ea152460 just include this, dammit 2016-10-20 23:11:07 +02:00
Thomas von Dein
19aa89be0c regen, added missing headers 2016-10-16 23:42:58 +02:00
Thomas von Dein
2ad190e921 fix indent error 2016-10-16 22:14:25 +02:00
git@daemon.de
28981bdbb1 better error handling for sscanf output in pbp import 2016-10-05 13:34:49 +02:00
git@daemon.de
8235272c41 rm unneeded defs 2016-10-05 13:34:09 +02:00
git@daemon.de
e953979ef6 get rid of strptime 2016-10-05 12:26:21 +02:00
git@daemon.de
af2418eb17 fix strptime compilation error 2016-10-05 11:48:22 +02:00
T.v.Dein
875ddd0991 Merge pull request #18 from aloisdg/patch-1
fix typo
2016-10-05 11:41:25 +02:00
TLINDEN
fcc16e17f4 more verbosity on -v 2016-08-26 15:45:04 +02:00
TLINDEN
39eaeaba0e more length shortcuts 2016-08-26 15:44:42 +02:00
TLINDEN
9132dd53bc using -v instead of -D to show number of recipients 2016-08-24 21:26:37 +02:00
git@daemon.de
ab5b6c0b13 display number of recipients with -D -d, see: http://www.daemon.de/blog/2017/08/24/436/how-backdoor-store-and-forward-public-key-crypto/ for details 2016-08-24 17:25:57 +02:00
T.v.Dein
3f1c2d9b15 Merge pull request #17 from torchhound/master
Fixed typos in README and README.pod
2016-07-11 10:31:23 +02:00
Joseph E.S. Cieslik
086e2407a6 Added fixes to README.pod that didn't get copied from README in the previous commit 2016-07-10 20:43:21 -04:00
Joseph E.S. Cieslik
c112136bba fixed typos in README and README.pod 2016-07-10 20:40:02 -04:00
TLINDEN
240d5f0a4a fix #16: look for glibtoolize on macosx 2016-07-10 20:50:14 +02:00
Alois
8cd4a18c40 fix typo 2016-07-05 14:56:35 +02:00
TLINDEN
46d93eb275 Merge branch 'master' of github.com:TLINDEN/pcp 2016-05-09 22:40:19 +02:00
TLINDEN
671352bc29 unfortunately my tab/spc config was wrong for a couple of years. fixed all tabs=>spaces+re-indent 2016-05-09 22:24:13 +02:00
git@daemon.de
59bf973859 regenerated 2016-01-21 13:14:18 +01:00
git@daemon.de
71c35bf815 fixed POD format bug: missing newline before heading 2016-01-21 13:13:59 +01:00
git@daemon.de
46ab78c56f fixed format warn 2016-01-21 13:13:21 +01:00
TLINDEN
a67149229f added is_utf8 license 2016-01-15 21:06:18 +01:00
git@daemon.de
feaa022b10 migrate to container, 4 try 2015-12-08 18:40:14 +01:00
git@daemon.de
26508281e8 migrate to container, 3 try 2015-12-08 18:36:15 +01:00
git@daemon.de
4b30a94f52 migrate to container, 2 try 2015-12-08 18:30:15 +01:00
git@daemon.de
fcca6f5a08 migrate to container, 1 try 2015-12-08 18:26:39 +01:00
TLINDEN
88b49e611b using blake2 checksums (pcp1 -C) now 2015-12-07 20:10:13 +01:00
TLINDEN
e847e7057d fix #14: use longterm secret key for signing in -Ac mode (anonymous encrypt+sign) 2015-12-07 14:13:27 +01:00
TLINDEN
d8c1f3cbd3 remove call to sodium_init() because already done on context.c 2015-11-15 17:11:30 +01:00
TLINDEN
ea1d20e0af remove call to sodium_init() because already done on context.c 2015-11-15 17:03:19 +01:00
TLINDEN
f7aa9d7aaf catch sodium_init() return 2015-11-15 17:02:51 +01:00
TLINDEN
ab3ff3182e fix POD 2015-11-15 16:46:43 +01:00
TLINDEN
935e28dff6 fix #15: dont free localtime() returned pointer 2015-11-15 16:35:56 +01:00
git@daemon.de
4e5c27c58c rm dbg print, fix #13 2015-10-23 12:25:52 +02:00
git@daemon.de
c7108ec47f fixed stream-reader bug on aix@ppc, which ignored the last z85 pkt sometimes due invalid call to ps_end() 2015-10-16 17:25:17 +02:00
git@daemon.de
4165e5d996 add aix pipe bug 2015-10-15 17:18:28 +02:00
git@daemon.de
5080e28e56 nothing 2015-10-15 17:18:15 +02:00
git@daemon.de
aa1aeb6975 nothing 2015-10-15 17:18:02 +02:00
git@daemon.de
b55e4ceb61 use openssl if no native md5 tool exists 2015-10-15 13:31:51 +02:00
git@daemon.de
0c5ab80654 fixed err() implementation, exit(eval) according to spec 2015-10-15 13:13:44 +02:00
git@daemon.de
359be6bce7 rm stdin=NULL, catched in main() anyway 2015-10-15 13:13:03 +02:00
git@daemon.de
a6940f8b87 abandon warn() not used anywhere else 2015-10-15 13:12:22 +02:00
TLINDEN
ae5be44182 fixed _gen_ctr_nonce(), reported in #12: invalid ctr comparision did lead to counter underflow 2015-10-14 19:53:03 +02:00
git@daemon.de
3a8d8c010f fixed memory leak during decrypt, reported in #10 2015-10-12 12:17:51 +02:00
git@daemon.de
61d3cbae83 regen 2015-10-12 12:17:16 +02:00
git@daemon.de
b4f264aab3 streamlined 2015-10-12 12:17:05 +02:00
TLINDEN
bbdda67a6e using constant time memcmp by C.Meessen 2015-08-27 11:19:24 +02:00
git@daemon.de
1b7681ee83 fix format for json int values 2015-08-24 20:31:04 +02:00
git@daemon.de
46bd857cc2 added osx support 2015-08-24 20:15:09 +02:00
git@daemon.de
44347793c1 rm printf 2015-08-24 20:14:54 +02:00
git@daemon.de
79874d5915 using json_int_t for uint32_ts json import 2015-08-24 16:31:18 +02:00
git@daemon.de
da70c4479e removed support to store unencrypted secret key 2015-08-19 20:53:46 +02:00
git@daemon.de
a9d4ef6ff3 updated 2015-08-17 20:25:42 +02:00
git@daemon.de
64a45583d0 added check for weak passphrase using entropy test 2015-08-17 20:15:20 +02:00
git@daemon.de
8fb7369d64 regenerated 2015-08-17 20:14:41 +02:00
TLINDEN
d04e5f3baf fixed decrypt from out buf 2015-08-17 11:17:12 +02:00
TLINDEN
d2ee10f071 fixed invalid free 2015-08-17 11:17:04 +02:00
TLINDEN
48283e7e04 fix :565:18: error, again, was a typo. not =- 1, but = -1. 2015-08-17 09:24:21 +02:00
TLINDEN
ac09fc1a2b fix :565:18: error: use of unary operator that may be intended as compound 2015-08-17 09:00:52 +02:00
TLINDEN
0d7282ad35 add entropy check for entered passphrases 2015-08-16 21:35:06 +02:00
TLINDEN
32030afd62 fix double free, add todo 2015-08-16 21:34:39 +02:00
TLINDEN
3b6933d34f regenerated 2015-08-15 20:39:02 +02:00
TLINDEN
c363dce7de using libsodiums size constants everywhere (keysizes and the likes) 2015-08-15 20:38:33 +02:00
TLINDEN
05741acd1a found another bug 2015-08-15 20:37:50 +02:00
TLINDEN
420e48d4e3 new error 2015-08-15 16:31:11 +02:00
TLINDEN
f091a28589 use mzero instead of wasting randomness 2015-08-15 13:04:30 +02:00
TLINDEN
7b3005e790 added context to pcp_readpass(), rm libpcp/getpass.c 2015-07-30 11:47:03 +02:00
TLINDEN
0046db9136 added extpass option 2015-07-30 11:46:17 +02:00
TLINDEN
deeb15e851 add pass idea 2015-07-29 17:47:55 +02:00
TLINDEN
27a9a96ae4 -C uses facilities of -x and -X 2015-07-22 07:59:28 +02:00
122 changed files with 5825 additions and 5736 deletions

View File

@@ -1,34 +1,26 @@
sudo: false
language: c
os:
- linux
addons:
apt:
packages:
- python-pip
- texinfo
compiler:
- clang
- gcc
before_install:
# runtime dependency
- git clone https://github.com/jedisct1/libsodium
- cd libsodium
- ./autogen.sh
- ./configure --prefix=/usr
- ./configure --prefix=$HOME/usr
- make
- sudo make install
- cd ..
#
# unittest dependencies, perl modules
- wget http://search.cpan.org/CPAN/authors/id/T/TL/TLINDEN/Config-General-2.56.tar.gz
- tar xvzf Config-General-2.56.tar.gz
- cd Config-General-2.56
- perl Makefile.PL && make
- sudo make install
- cd ..
- wget http://search.cpan.org/CPAN/authors/id/C/CH/CHORNY/Tie-IxHash-1.23.tar.gz
- tar xvzf Tie-IxHash-1.23.tar.gz
- cd Tie-IxHash-1.23
- perl Makefile.PL && make
- sudo make install
- cd ..
- wget http://search.cpan.org/CPAN/authors/id/I/IN/INGY/YAML-1.14.tar.gz
- tar xvfz YAML-1.14.tar.gz
- cd YAML-1.14
- perl Makefile.PL && make
- sudo make install
- make install
- cd ..
#
# for debugging - just in case, uncomment this and the next if needed
@@ -45,24 +37,21 @@ before_install:
#- sudo apt-get install libc6-dbg
#
# python bindings runtime dependencies
- sudo apt-get update -qq
- sudo apt-get install python-pip texinfo
- git clone https://github.com/atgreen/libffi
- cd libffi
- ./autogen.sh
- ./configure --prefix=/usr
- make
- sudo make install
- cd ..
- sudo pip install cffi
#- git clone https://github.com/atgreen/libffi
#- cd libffi
#- ./autogen.sh
#- ./configure --prefix=/usr
#- make
#- sudo make install
#- cd ..
#- sudo pip install cffi
#
# finally prepare autoconf stuff
- ./autogen.sh
compiler:
- clang
- gcc
script:
- ./configure --enable-python-binding
#- ./configure --enable-python-binding
- LD_LIBRARY_PATH=$HOME/usr/lib ./configure --with-libsodium=$HOME/usr
- make
- make check
- make test

29
.woodpecker/build.yaml Normal file
View File

@@ -0,0 +1,29 @@
matrix:
platform:
- linux/amd64
labels:
platform: ${platform}
steps:
build:
when:
event: [push]
image: alpine:latest
commands:
- apk update
- apk add --no-cache bash build-base gdb perl libsodium libsodium-dev libbsd libbsd-dev jansson jansson-dev db db-dev pkgconfig meson ninja
- meson setup --reconfigure build
- ninja -C build
test:
when:
event: [push]
image: alpine:latest
commands:
- apk update
- apk add --no-cache bash build-base gdb perl libsodium libsodium-dev libbsd libbsd-dev jansson jansson-dev db db-dev pkgconfig meson ninja
- meson setup --reconfigure build
- ninja -C build test

54
.woodpecker/release.sh Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/bash
# This is my own simple codeberg generic releaser. It takes to
# binaries to be uploaded as arguments and takes every other args from
# env. Works on tags or normal commits (push), tags must start with v.
set -e
die() {
echo $*
exit 1
}
if test -z "$DEPLOY_TOKEN"; then
die "token DEPLOY_TOKEN not set"
fi
git fetch --all
# determine current tag or commit hash
version="$CI_COMMIT_TAG"
previous=""
log=""
if test -z "$version"; then
version="${CI_COMMIT_SHA:0:6}"
log=$(git log -1 --oneline)
else
previous=$(git tag -l | grep -E "^v" | tac | grep -A1 "$version" | tail -1)
log=$(git log -1 --oneline "${previous}..${version}" | sed 's|^|- |g')
fi
# release body
printf "# Changes\n\n %s\n" "$log" > body.txt
# create the release
https --ignore-stdin --check-status -b -A bearer -a "$DEPLOY_TOKEN" POST \
"https://codeberg.org/api/v1/repos/${CI_REPO_OWNER}/${CI_REPO_NAME}/releases" \
tag_name="$version" name="Release $version" body=@body.txt > release.json
# we need the id to upload files
ID=$(jq -r .id < release.json)
if test -z "$ID"; then
cat release.json
die "failed to create release"
fi
# actually upload
for file in "$@"; do
https --ignore-stdin --check-status -A bearer -a "$DEPLOY_TOKEN" -f POST \
"https://codeberg.org/api/v1/repos/${CI_REPO_OWNER}/${CI_REPO_NAME}/releases/$ID/assets" \
"name=${file}" "attachment@${file}"
done

28
.woodpecker/release.yaml Normal file
View File

@@ -0,0 +1,28 @@
# build release
labels:
platform: linux/amd64
steps:
dist:
when:
event: [tag,manual]
image: alpine:latest
commands:
- apk update
- apk add --no-cache bash build-base gdb perl libsodium libsodium-dev libbsd libbsd-dev jansson jansson-dev db db-dev pkgconfig meson ninja git
- meson setup --reconfigure --buildtype=release build
- meson dist -C build --formats xztar,gztar,zip --no-tests
- mv build/meson-dist/* .
release:
image: alpine:latest
when:
event: [tag,manual]
environment:
DEPLOY_TOKEN:
from_secret: DEPLOY_TOKEN
commands:
- apk update
- apk add --no-cache bash httpie jq git
- .woodpecker/release.sh pcp-*

19
.woodpecker/test.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
yq '.steps.test-gdbm.commands' < .woodpecker/build.yaml \
| grep -- - | grep -v apk | sed 's/^\- //' \
| while read COMMAND; do
echo "$COMMAND" | bash -e > debug.log 2>&1
if test $? -ne 0; then
echo "fail - $COMMAND"
if test -s debug.log; then
cat debug.log
else
echo exit 1
fi
else
echo "ok - $COMMAND"
fi
done
rm -f debug.log

View File

@@ -1,3 +1,46 @@
0.4.1
Merged upstream patch:
https://github.com/zeromq/libzmq/pull/2322,
which fixes:
https://github.com/zeromq/libzmq/issues/903:
Problem: zmq_z85_decode does not validate its
input. Solution: added checks for invalid
characters and overflows.
0.4.0
Changed -C again: doesnt support a key argument
anymore, instead I use the facilities I already
have in place (-x and -X). Also, I don't generate
an extra hash for the key anymore.
Removed libpcp/getpass.c, not used anymore.
Added --extpass (implementation from encfs, but
somewhat modified).
Moved src/readpass.c to libpcp/.
Added check for weak passphrases using entropy
test. Used with -k.
Removed support for unencrypted secret key storage
so, pcp aims to be secure by default and fails
safely.
Using cst_time_memcpy by Christophe Meessen instead
of libc's memcpy: constant time memcpy is much more
secure than the default, especially in our context.
Anonymous encrypted files are now signed with primary
secret key, so that the recipient will be able to
verify the signature.
Added -v support for -d and -e.
Removed endian conversion stuff. see util.c for details.
Fixed: use key signatures for vault checksum calc as well.
0.3.0
Changed publuc key signature storage, previously
I didn't add the actual signature, therefore a

2
FAQ
View File

@@ -9,7 +9,7 @@ make LDFLAGS="-all-static -s"
A passphrase like Ahc<e3% is not really secure. First
it's difficult to memorize, second it's easy for a computer
to compute. The better aproach is to use a passphrase
you can easily momorize and which is hard for a computer
you can easily memorize and which is hard for a computer
to compute (i.e. to guess) like: Phantom orchestra boredom popcorn.
Read [1] to learn more.

168
README
View File

@@ -1,168 +0,0 @@
DESCRIPTION
Pretty Curved Privacy (pcp1) is a commandline utility which can be used
to encrypt files. pcp1 uses eliptc curve cryptography for encryption
(CURVE25519 by Dan J. Bernstein). While CURVE25519 is no worldwide
accepted standard it hasn't been compromised by the NSA - which might be
better, depending on your point of view.
Caution: since CURVE25519 is no accepted standard, pcp1 has to be
considered as experimental software. In fact, I wrote it just to learn
about the curve and see how it works.
Beside some differences it works like GNUPG. So, if you already know how
to use gpg, you'll feel almost home.
QUICKSTART
Lets say, Alicia and Bobby want to exchange encrypted messages. Here's
what the've got to do.
First, both have create a secret key:
Alicia Bobby
pcp1 -k pcp1 -k
After entering their name, email address and a passphrase to protect the
key, it will be stored in their vault file (by default ~/.pcpvault).
Now, both of them have to export the public key, which has to be
imported by the other one. With pcp you can export the public part of
your primary key, but the better solution is to export a derived public
key especially for the recipient:
Alicia Bobby
pcp1 -p -r Bobby -O alicia.pub pcp1 -p -r Alicia -O bobby.pub
They've to exchange the public key somehow (which is not my problem at
the moment, use ssh, encrypted mail, whatever). Once exchanged, they
have to import it:
Alicia Bobby
pcp1 -K -I bobby.pub pcp1 -K -I alicia.pub
They will see a response as this when done:
key 0x29A323A2C295D391 added to .pcpvault.
Now, Alicia finally writes the secret message, encrypts it and sends it
to Bobby, who in turn decrypts it:
Alicia Bobby
echo "Love you, honey" > letter
pcp1 -e -r Bobby -I letter -O letter.asc
cat letter.asc | mail bobby@foo.bar
pcp1 -d -I letter.asc | less
And that's it.
Please note the big difference to GPG though: both Alicia AND Bobby have
to enter the passphrase for their secret key! That's the way CURVE25519
works: you encrypt a message using your secret key and the recipients
public key and the recipient does the opposite, he uses his secret key
and your public key to actually decrypt the message.
Oh - and if you're wondering why I named them Alicia and Bobby: I was
just sick of Alice and Bob. We're running NSA-free, so we're using other
sample names as well.
FILES AND PIPES
Pcp behaves like any other unix tool. If not otherwise specified it will
read input from standard input (STDIN) and print output to standard
output (STDOUT). For instance:
pcp1 -e -O output
will read the text to be encrypted from standard input, because -I has
not been specified. It works the same with -O:
pcp1 -e -I myfile
In this case the encrypted result will be written to standard output.
Therefore it is possible to use pcp within pipes. Another more realistic
example:
ssh remote cat file | pcp1 -ez | mailx -s 'as requested' bob@somewhere
here we encrypt a file symmetrically without downloading it from a
remote ssh server and sending the encrypted result via email to someone.
The behavior is the same with any other functionality where files are
involved like importing or exporting keys. However, there's one
exception: If the option -X (--password-file) has been used and is set
to -, then this will take precedence over any other possible use of
standard input. So if you want to encrypt something and don't specify an
input file you cannot use -X -, and vice versa. IF you use -X - the
passphrase will be read from standard input, which then can't be used
further for input files elsewhere. Pcp will exit with an error in such a
case. =head1 INSTALLATION
There are currently no packages available, so pcp has to be compiled
from source. Follow these steps:
First, you will need libsodium:
git clone git://github.com/jedisct1/libsodium.git
cd libsodium
./autogen.sh
./configure && make check
sudo make install
sudo ldconfig
cd ..
Next, pcp:
git clone git://github.com/tlinden/pcp.git
cd pcp
./configure
sudo make install
cd ..
Optionally, you might run the unit tests:
make test
DOCUMENTATION
To learn how to use pcp, read the manpage:
man pcp1
COPYRIGHT
Copyright (c) 2013-2015 by T.v.Dein <tom AT vondein DOT org>
ADDITIONAL COPYRIGHTS
ZeroMQ Z85 encoding routine
Copyright (c) 2007-2013 iMatix Corporation
Copyright (c) 2009-2011 250bpm s.r.o.
Copyright (c) 2010-2011 Miru Limited
Copyright (c) 2011 VMware, Inc.
Copyright (c) 2012 Spotify AB
Tarsnap readpass helpers
Copyright 2009 Colin Percival
jen_hash() hash algorithm
Bob Jenkins, Public Domain.
UTHASH hashing macros
Copyright (c) 2003-2013, Troy D. Hanson
Random art image from OpenSSH keygen
Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
Comitted by Alexander von Gernler in rev 1.7.
Every incorporated source code is opensource and licensed under the GPL
as well.
AUTHORS
*T.v.Dein <tom AT vondein DOT org*>
LICENSE
Licensed under the GNU GENERAL PUBLIC LICENSE version 3.
HOME
The homepage of Pretty Curved Privacy can be found on
http://www.daemon.de/PrettyCurvedPrivacy. The source is on Github:
https://github.com/TLINDEN/pcp

187
README.md Normal file
View File

@@ -0,0 +1,187 @@
# Pretty Curved Privacy
Pretty Curved Privacy (pcp1) is a commandline utility which can be used
to encrypt files. pcp1 uses eliptc curve cryptography for encryption
(CURVE25519 by Dan J. Bernstein). While CURVE25519 is no worldwide
accepted standard it hasn't been compromised by the NSA - which might be
better, depending on your point of view.
Caution: since CURVE25519 is no accepted standard, pcp1 has to be
considered as experimental software. In fact, I wrote it just to learn
about the curve and see how it works.
Beside some differences it works like GNUPG. So, if you already know how
to use gpg, you'll feel almost home.
# QUICKSTART
Lets say, Alicia and Bobby want to exchange encrypted messages. Here's
what the've got to do.
First, both have create a secret key:
Alicia Bobby
pcp1 -k pcp1 -k
After entering their name, email address and a passphrase to protect the
key, it will be stored in their vault file (by default ~/.pcpvault).
Now, both of them have to export the public key, which has to be
imported by the other one. With pcp you can export the public part of
your primary key, but the better solution is to export a derived public
key especially for the recipient:
Alicia Bobby
pcp1 -p -r Bobby -O alicia.pub pcp1 -p -r Alicia -O bobby.pub
They've to exchange the public key somehow (which is not my problem at
the moment, use ssh, encrypted mail, whatever). Once exchanged, they
have to import it:
Alicia Bobby
pcp1 -K -I bobby.pub pcp1 -K -I alicia.pub
They will see a response as this when done:
key 0x29A323A2C295D391 added to .pcpvault.
Now, Alicia finally writes the secret message, encrypts it and sends it
to Bobby, who in turn decrypts it:
Alicia Bobby
echo "Love you, honey" > letter
pcp1 -e -r Bobby -I letter -O letter.asc
cat letter.asc | mail bobby@foo.bar
pcp1 -d -I letter.asc | less
And that's it.
Please note the big difference to GPG though: both Alicia AND Bobby have
to enter the passphrase for their secret key! That's the way CURVE25519
works: you encrypt a message using your secret key and the recipients
public key and the recipient does the opposite, he uses his secret key
and your public key to actually decrypt the message.
Oh - and if you're wondering why I named them Alicia and Bobby: I was
just sick of Alice and Bob. We're running NSA-free, so we're using other
sample names as well.
# FILES AND PIPES
Pcp behaves like any other unix tool. If not otherwise specified it will
read input from standard input (STDIN) and print output to standard
output (STDOUT). For instance:
pcp1 -e -O output
will read the text to be encrypted from standard input, because -I has
not been specified. It works the same with -O:
pcp1 -e -I myfile
In this case the encrypted result will be written to standard output.
Therefore it is possible to use pcp within pipes. Another more realistic
example:
ssh remote cat file | pcp1 -ez | mailx -s 'as requested' bob@somewhere
here we encrypt a file symmetrically without downloading it from a
remote ssh server and sending the encrypted result via email to someone.
The behavior is the same with any other functionality where files are
involved like importing or exporting keys. However, there's one
exception: If the option -X (--password-file) has been used and is set
to -, then this will take precedence over any other possible use of
standard input. So if you want to encrypt something and don't specify an
input file you cannot use -X -, and vice versa. IF you use -X - the
passphrase will be read from standard input, which then can't be used
further for input files elsewhere. Pcp will exit with an error in such a
case.
# INSTALLATION
here are currently no packages available, so pcp has to be compiled
from source. Follow these steps:
First, you will need libsodium:
git clone git://github.com/jedisct1/libsodium.git
cd libsodium
./autogen.sh
./configure && make check
sudo make install
sudo ldconfig
cd ..
If you want to have JSON support, you'll need to install the Jansson
library (optional):
git clone git://github.com/akheron/jansson.git
cd jansson
autoreconf -i
./configure && make
sudo make install
cd ..
In order to use the python binding, you need to install the cffi python
package.
Next, build pcp:
git clone git://codeberg.org/scip/pcp.git
cd pcp
meson setup build
ninja -C build
sudo ninja -C install
Optionally, you might run the unit tests:
make test
DOCUMENTATION
To learn how to use pcp, read the manpage:
man pcp1
# COPYRIGHT
Copyright (c) 2013-2015 by T.v.Dein <tom AT vondein DOT org>
## ZeroMQ Z85 encoding routine:
- Copyright (c) 2007-2013 iMatix Corporation
- Copyright (c) 2009-2011 250bpm s.r.o.
- Copyright (c) 2010-2011 Miru Limited
- Copyright (c) 2011 VMware, Inc.
- Copyright (c) 2012 Spotify AB
## Tarsnap readpass helpers
Copyright 2009 Colin Percival
## jen_hash() hash algorithm
Bob Jenkins, Public Domain.
## UTHASH hashing macros
Copyright (c) 2003-2013, Troy D. Hanson
# Random art image from OpenSSH keygen
Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
Comitted by Alexander von Gernler in rev 1.7.
# AUTHORS
*T.v.Dein <tom AT vondein DOT org*>
# LICENSE
Licensed under the GNU GENERAL PUBLIC LICENSE version 3.

View File

@@ -1,203 +0,0 @@
=begin html
<a href="https://travis-ci.org/TLINDEN/pcp"><img
src="https://travis-ci.org/TLINDEN/pcp.svg?branch=master"
alt="build status"/></a>
<a href="https://ci.appveyor.com/project/TLINDEN/pcp"><img
src="https://ci.appveyor.com/api/projects/status/7e833vup5pqhse83?svg=true"
alt="build status"/></a>
=end html
=head1 DESCRIPTION
B<Pretty Curved Privacy> (pcp1) is a commandline utility which can
be used to encrypt files. B<pcp1> uses eliptc curve cryptography
for encryption (CURVE25519 by Dan J. Bernstein). While CURVE25519
is no worldwide accepted standard it hasn't been compromised by
the NSA - which might be better, depending on your point of view.
B<Caution>: since CURVE25519 is no accepted standard, B<pcp1> has
to be considered as experimental software. In fact, I wrote it just
to learn about the curve and see how it works.
Beside some differences it works like B<GNUPG>. So, if you already
know how to use gpg, you'll feel almost home.
=head1 QUICKSTART
Lets say, Alicia and Bobby want to exchange encrypted messages.
Here's what the've got to do.
First, both have create a secret key:
Alicia Bobby
pcp1 -k pcp1 -k
After entering their name, email address and a passphrase to protect
the key, it will be stored in their B<vault file> (by default ~/.pcpvault).
Now, both of them have to export the public key, which has to be
imported by the other one. With B<pcp> you can export the public
part of your primary key, but the better solution is to export
a derived public key especially for the recipient:
Alicia Bobby
pcp1 -p -r Bobby -O alicia.pub pcp1 -p -r Alicia -O bobby.pub
They've to exchange the public key somehow (which is not my
problem at the moment, use ssh, encrypted mail, whatever). Once exchanged,
they have to import it:
Alicia Bobby
pcp1 -K -I bobby.pub pcp1 -K -I alicia.pub
They will see a response as this when done:
key 0x29A323A2C295D391 added to .pcpvault.
Now, Alicia finally writes the secret message, encrypts it and
sends it to Bobby, who in turn decrypts it:
Alicia Bobby
echo "Love you, honey" > letter
pcp1 -e -r Bobby -I letter -O letter.asc
cat letter.asc | mail bobby@foo.bar
pcp1 -d -I letter.asc | less
And that's it.
Please note the big difference to B<GPG> though: both Alicia
AND Bobby have to enter the passphrase for their secret key!
That's the way CURVE25519 works: you encrypt a message using
your secret key and the recipients public key and the recipient
does the opposite, he uses his secret key and your public key
to actually decrypt the message.
Oh - and if you're wondering why I named them Alicia and Bobby:
I was just sick of Alice and Bob. We're running NSA-free, so we're
using other sample names as well.
=head1 FILES AND PIPES
Pcp behaves like any other unix tool. If not otherwise specified
it will read input from standard input (STDIN) and print output
to standard output (STDOUT). For instance:
pcp1 -e -O output
will read the text to be encrypted from standard input, because B<-I>
has not been specified. It works the same with B<-O>:
pcp1 -e -I myfile
In this case the encrypted result will be written to standard output.
Therefore it is possible to use pcp within pipes. Another more
realistic example:
ssh remote cat file | pcp1 -ez | mailx -s 'as requested' bob@somewhere
here we encrypt a file symmetrically without downloading it from a
remote ssh server and sending the encrypted result via email to
someone.
The behavior is the same with any other functionality where files are involved
like importing or exporting keys. However, there's one exception:
If the option B<-X> (B<--password-file>) has been used and is set
to B<->, then this will take precedence over any other possible use
of standard input. So if you want to encrypt something and don't
specify an input file you cannot use B<-X ->, and vice versa. IF
you use B<-X -> the passphrase will be read from standard input, which
then can't be used further for input files elsewhere. Pcp will exit
with an error in such a case.
=head1 INSTALLATION
There are currently no packages available, so B<pcp> has to be
compiled from source. Follow these steps:
First, you will need libsodium:
git clone git://github.com/jedisct1/libsodium.git
cd libsodium
./autogen.sh
./configure && make check
sudo make install
sudo ldconfig
cd ..
Next, pcp:
git clone git://github.com/tlinden/pcp.git
cd pcp
./configure
sudo make install
cd ..
Optionally, you might run the unit tests:
make test
=head1 DOCUMENTATION
To learn how to use B<pcp>, read the manpage:
man pcp1
=head1 COPYRIGHT
Copyright (c) 2013-2015 by T.v.Dein <tom AT vondein DOT org>
=head1 ADDITIONAL COPYRIGHTS
=over
=item B<ZeroMQ Z85 encoding routine>
Copyright (c) 2007-2013 iMatix Corporation
Copyright (c) 2009-2011 250bpm s.r.o.
Copyright (c) 2010-2011 Miru Limited
Copyright (c) 2011 VMware, Inc.
Copyright (c) 2012 Spotify AB
=item B<Tarsnap readpass helpers>
Copyright 2009 Colin Percival
=item B<jen_hash() hash algorithm>
Bob Jenkins, Public Domain.
=item B<UTHASH hashing macros>
Copyright (c) 2003-2013, Troy D. Hanson
=item B<Random art image from OpenSSH keygen>
Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
Comitted by Alexander von Gernler in rev 1.7.
=back
Every incorporated source code is opensource and licensed
under the B<GPL> as well.
=head1 AUTHORS
I<T.v.Dein <tom AT vondein DOT org>>
=head1 LICENSE
Licensed under the GNU GENERAL PUBLIC LICENSE version 3.
=head1 HOME
The homepage of Pretty Curved Privacy can be found on
http://www.daemon.de/PrettyCurvedPrivacy. The source is
on Github: https://github.com/TLINDEN/pcp
=cut

8
TODO
View File

@@ -1,3 +1,6 @@
JSON output has \0 always appended check from where this comes
pcpstream.c: use static tmp buffers, avoid alloc mem during each iteration
detach keysig generation from pub key export, so that an existing
keysig can be verified later.
@@ -10,12 +13,7 @@ malloc() new pointers in functions only if not NULL, e.g. pcp_gennonce()
check pub key count in pcp.c before calling verify signature, croak if count==0
vault checksum: add keysigs as well
Add newlines to headers in define.h, so strlen() later catches the whole length.
Check is_utf8 license.
also found in https://gd.meizo.com/_files/lpc/ext/utf8.c
c++ destructor double free mess

View File

@@ -1 +1 @@
0.3.0
0.4.1

View File

@@ -26,3 +26,5 @@ build_script:
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; ./configure"'
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; cat config.log"'
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; make"'
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; make check"'
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; make test"'

View File

@@ -1,116 +0,0 @@
#!/bin/sh
mode=config
case $1 in
clean)
mode=clean
;;
gen)
mode=gen
;;
-h|--help|help|\?)
echo "Usage: $0 [clean|gen]"
exit 1
;;
esac
if test "$mode" = "gen"; then
# generate the install include file
(echo "#ifndef _HAVE_PCP"; echo "#define _HAVE_PCP"; echo) > include/pcp.h
(echo "#ifdef __cplusplus"; echo "extern \"C\" {"; echo "#endif"; echo) >> include/pcp.h
echo "#include \"pcp/config.h\"" >> include/pcp.h
ls include/pcp/*.h | sed 's#include/##' | while read include; do
echo "#include \"$include\"" >> include/pcp.h
done
(echo "#ifdef __cplusplus"; echo "}"; echo "#endif"; echo) >> include/pcp.h
(echo; echo "#endif") >> include/pcp.h
# generate the version file
maj=`egrep "#define PCP_VERSION_MAJOR" include/pcp/version.h | awk '{print $3}'`
min=`egrep "#define PCP_VERSION_MINOR" include/pcp/version.h | awk '{print $3}'`
pat=`egrep "#define PCP_VERSION_PATCH" include/pcp/version.h | awk '{print $3}'`
echo -n "$maj.$min.$pat" > VERSION
# generate the manpage
echo "=head1 NAME
Pretty Curved Privacy - File encryption using eliptic curve cryptography.
=head1 SYNOPSIS
" > man/pcp1.pod
cat src/usage.txt | sed "s/^/ /g" >> man/pcp1.pod
cat man/options.pod >> man/pcp1.pod
cat man/pcp.pod >> man/pcp1.pod
cat man/details.pod >> man/pcp1.pod
cat man/footer.pod >> man/pcp1.pod
pod2man -r "PCP `cat VERSION`" -c "USER CONTRIBUTED DOCUMENTATION" man/pcp1.pod > man/pcp1.1
pod2html man/pcp1.pod > man/pcp1.html
# generate the top level readme
cat man/badges man/pcp.pod man/install.pod man/footer.pod > README.pod
pod2text README.pod > README
# generate usage.h
(cd src && ./usage.sh)
# generate pypcp types
cd bindings/py
./gencffi.pl ../../include/pcp/*.h > pypcp/raw.py
cd -
exit
fi
if test "$mode" = "config"; then
mkdir -p ./config
if ! command -v libtoolize >/dev/null 2>&1; then
echo "could not find libtool." 1>&2
exit 1
fi
if ! command -v autoreconf >/dev/null 2>&1; then
echo "could not find autoreconf." 1>&2
exit 1
fi
autoreconf --install --force --verbose -I config
fi
#
# normal autogen stuff
cat <<EOF > clean.sh
#!/bin/sh
find . -name Makefile -exec rm {} \; > /dev/null 2>&1
find . -name Makefile.in -exec rm {} \; > /dev/null 2>&1
find . -name "*~" -exec rm {} \; > /dev/null 2>&1
find . -name config.h -exec rm {} \; > /dev/null 2>&1
find . -name "stamp*" -exec rm {} \; > /dev/null 2>&1
find . -name .deps -exec rm -rf {} \; > /dev/null 2>&1
find . -name .libs -exec rm -rf {} \; > /dev/null 2>&1
find . -name .o -exec rm -rf {} \; > /dev/null 2>&1
find . -name .lo -exec rm -rf {} \; > /dev/null 2>&1
find . -name .pyc -exec rm -rf {} \; > /dev/null 2>&1
find . -name .dirstamp -exec rm -rf {} \; > /dev/null 2>&1
rm -rf aclocal.m4 libtool configure config.* config autom4te.cache tests/test* tests/v* tests/stresstest/* libpcp/libpcp1.pc
rm clean.sh
EOF
chmod 700 clean.sh
rm -rf include/pcp/config.h.in~ libpcp/stamp-h1 autom4te.cache
sleep 1
touch Makefile.in configure */Makefile.in

View File

@@ -54,7 +54,7 @@ bool Crypto::encrypt(FILE *in, FILE *out, bool sign) {
Pcpstream *pin = ps_new_file(in);
Pcpstream *pout = ps_new_file(out);
size_t clen = pcp_encrypt_stream(PTX->ptx, pin, pout, S.K, pubhash, sign, 0); // FIXME: add anon support
size_t clen = pcp_encrypt_stream(PTX->ptx, pin, pout, S.K, S.K, pubhash, sign, 0); // FIXME: add anon support
if(clen <= 0)
throw exception(PTX);
ps_close(pin);

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -41,12 +41,12 @@ namespace pcp {
std::string msg;
PCPCTX *ptx = P->ptx;
if(ptx->pcp_errset == 1) {
msg = ptx->pcp_err;
msg = ptx->pcp_err;
}
if(errno) {
msg += std::string("\nError: ")
+ std::string(strerror(errno))
+ std::string("\n");
msg += std::string("\nError: ")
+ std::string(strerror(errno))
+ std::string("\n");
}
return msg;
}

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -83,8 +83,8 @@ namespace pcp {
Key(PcpContext *P, bool generate);
Key(PcpContext *P, const std::string& passphrase);
Key(PcpContext *P, const std::string& passphrase,
const std::string& owner,
const std::string& mail);
const std::string& owner,
const std::string& mail);
Key(PcpContext *P, pcp_key_t *k);
Key(PcpContext *P, pcp_key_t *k, bool store);
Key(PcpContext *P, std::string &z85encoded, std::string& passphrase);

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -53,8 +53,8 @@ Key::Key(PcpContext *P, const string& passphrase) {
}
Key::Key(PcpContext *P, const string& passphrase,
const string& owner,
const string& mail) {
const string& owner,
const string& mail) {
stored = false;
pcp_key_t *_K = pcpkey_new();
K = pcpkey_encrypt(P->ptx, _K, (char *)passphrase.c_str());

View File

@@ -2,28 +2,28 @@
use Data::Dumper;
my %sobytes = (
'crypto_box_NONCEBYTES' => 24,
'crypto_box_PUBLICKEYBYTES' => 32,
'crypto_box_SECRETKEYBYTES' => 32,
'crypto_box_ZEROBYTES' => 32,
'crypto_box_BOXZEROBYTES' => 16,
'crypto_box_MACBYTES' => 16,
'crypto_secretbox_KEYBYTES' => 32,
'crypto_secretbox_NONCEBYTES' => 24,
'crypto_secretbox_ZEROBYTES' => 32,
'crypto_secretbox_BOXZEROBYTES' => 16,
'crypto_secretbox_MACBYTES' => 16,
'crypto_sign_PUBLICKEYBYTES' => 32,
'crypto_sign_SECRETKEYBYTES' => 64,
'crypto_sign_SEEDBYTES' => 32,
'crypto_sign_BYTES' => 64,
'crypto_stream_KEYBYTES' => 32,
'crypto_stream_NONCEBYTES' => 24,
'crypto_generichash_BYTES' => 32,
'crypto_scalarmult_curve25519_BYTES' => 32,
'crypto_scalarmult_BYTES' => 32,
'crypto_generichash_BYTES_MAX' => 64,
);
'crypto_box_NONCEBYTES' => 24,
'crypto_box_PUBLICKEYBYTES' => 32,
'crypto_box_SECRETKEYBYTES' => 32,
'crypto_box_ZEROBYTES' => 32,
'crypto_box_BOXZEROBYTES' => 16,
'crypto_box_MACBYTES' => 16,
'crypto_secretbox_KEYBYTES' => 32,
'crypto_secretbox_NONCEBYTES' => 24,
'crypto_secretbox_ZEROBYTES' => 32,
'crypto_secretbox_BOXZEROBYTES' => 16,
'crypto_secretbox_MACBYTES' => 16,
'crypto_sign_PUBLICKEYBYTES' => 32,
'crypto_sign_SECRETKEYBYTES' => 64,
'crypto_sign_SEEDBYTES' => 32,
'crypto_sign_BYTES' => 64,
'crypto_stream_KEYBYTES' => 32,
'crypto_stream_NONCEBYTES' => 24,
'crypto_generichash_BYTES' => 32,
'crypto_scalarmult_curve25519_BYTES' => 32,
'crypto_scalarmult_BYTES' => 32,
'crypto_generichash_BYTES_MAX' => 64,
);
my @ignore = qw(uthash.h);
@@ -87,19 +87,19 @@ foreach my $head (@ARGV) {
print "PCP_RAW_CODE = '''\n";
print qq(
typedef enum {
JSON_OBJECT,
JSON_ARRAY,
JSON_STRING,
JSON_INTEGER,
JSON_REAL,
JSON_TRUE,
JSON_FALSE,
JSON_NULL
JSON_OBJECT,
JSON_ARRAY,
JSON_STRING,
JSON_INTEGER,
JSON_REAL,
JSON_TRUE,
JSON_FALSE,
JSON_NULL
} json_type;
typedef struct json_t {
json_type type;
size_t refcount;
json_type type;
size_t refcount;
} json_t;
);
print join "\n", @typedefs;

View File

@@ -1,28 +1,28 @@
PCP_RAW_CODE = '''
typedef enum {
JSON_OBJECT,
JSON_ARRAY,
JSON_STRING,
JSON_INTEGER,
JSON_REAL,
JSON_TRUE,
JSON_FALSE,
JSON_NULL
JSON_OBJECT,
JSON_ARRAY,
JSON_STRING,
JSON_INTEGER,
JSON_REAL,
JSON_TRUE,
JSON_FALSE,
JSON_NULL
} json_type;
typedef struct json_t {
json_type type;
size_t refcount;
json_type type;
size_t refcount;
} json_t;
/*** ./gencffi.pl: from ../../include/pcp/defines.h:172 */
/*** ./gencffi.pl: from ../../include/pcp/defines.h:185 */
typedef unsigned char byte;
/*** ./gencffi.pl: from ../../include/pcp/defines.h:172 */
/*** ./gencffi.pl: from ../../include/pcp/defines.h:185 */
typedef unsigned short dbyte;
/*** ./gencffi.pl: from ../../include/pcp/defines.h:172 */
/*** ./gencffi.pl: from ../../include/pcp/defines.h:185 */
typedef unsigned int qbyte;
/*** ./gencffi.pl: from ../../include/pcp/plist.h:83 */
@@ -84,45 +84,44 @@ struct _plist_t {
/*** ./gencffi.pl: from ../../include/pcp/structs.h:380 */
struct _pcp_key_t {
byte masterpub[32]; /**< ED25519 master public key signing key */
byte mastersecret[64]; /**< ED25519 master secret key signing key */
byte pub[32]; /**< Curve25519 encryption public key */
byte secret[32]; /**< Curve25519 encryption secret key */
byte edpub[32]; /**< ED25519 public signing key */
byte edsecret[64]; /**< ED25519 secret signing key */
byte nonce[24]; /**< random nonce used to encrypt secret keys */
byte encrypted[176]; /**< concatenated and encrypted secret keys */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
byte masterpub[LEDPUB]; /**< ED25519 master public key signing key */
byte mastersecret[LEDSEC]; /**< ED25519 master secret key signing key */
byte pub[LBOXPUB]; /**< Curve25519 encryption public key */
byte secret[LBOXSEC]; /**< Curve25519 encryption secret key */
byte edpub[LEDPUB]; /**< ED25519 public signing key */
byte edsecret[LEDSEC]; /**< ED25519 secret signing key */
byte nonce[LNONCE]; /**< random nonce used to encrypt secret keys */
byte encrypted[LSEC]; /**< concatenated and encrypted secret keys */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
byte hh[56];
};
/*** ./gencffi.pl: from ../../include/pcp/structs.h:380 */
struct _pcp_pubkey_t {
byte masterpub[32]; /**< ED25519 master public key signing key */
byte sigpub[32]; /**< ED25519 public signing key */
byte pub[32]; /**< Curve25519 encryption public key */
byte edpub[32]; /**< ED25519 public signing key (FIXME: huh? 2 of them???) */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
uint8_t valid; /**< 1 if import signature verified, 0 if not */
byte masterpub[LEDPUB]; /**< ED25519 master public key signing key */
byte pub[LBOXPUB]; /**< Curve25519 encryption public key */
byte edpub[LEDPUB]; /**< ED25519 public signing key (FIXME: huh? 2 of them???) */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
uint8_t valid; /**< 1 if import signature verified, 0 if not */
byte signature[128]; /**< raw binary blob of pubkey export signature */
byte hh[56];
};
/*** ./gencffi.pl: from ../../include/pcp/structs.h:380 */
struct _pbp_pubkey_t {
byte sigpub[32];
byte masterpub[32];
byte edpub[32];
byte pub[32];
char iso_ctime[32];
@@ -143,7 +142,7 @@ struct _pcp_keysig_t {
uint8_t type;
uint32_t size;
char id[17];
byte checksum[32];
byte checksum[LSHA];
byte *blob;
byte hh[56];
};
@@ -170,14 +169,14 @@ struct _vault_t {
time_t modified; /**< mtime */
mode_t mode; /**< File mode */
uint32_t version; /**< Vault version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
byte checksum[LSHA]; /**< SHA256 checksum over the whole vault */
};
/*** ./gencffi.pl: from ../../include/pcp/structs.h:380 */
struct _vault_header_t {
uint8_t fileid; /**< File id, proprietary. Marks the vault as a vault */
uint32_t version; /**< File version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
byte checksum[LSHA]; /**< SHA256 checksum over the whole vault */
};
/*** ./gencffi.pl: from ../../include/pcp/structs.h:380 */
@@ -185,7 +184,7 @@ struct _vault_item_header_t {
uint8_t type; /**< Item type (secret key, public, key, keysig, \see _PCP_KEY_TYPES */
uint32_t size; /**< Size of the item */
uint32_t version; /**< Version of the item */
byte checksum[32]; /**< SHA256 checksum of the item */
byte checksum[LSHA]; /**< SHA256 checksum of the item */
};
/*** ./gencffi.pl: from ../../include/pcp/structs.h:380 */
@@ -207,6 +206,7 @@ struct _pcp_stream_t {
Buffer *cache; /**< The caching Buffer object (for look ahead read) */
Buffer *next; /**< The caching Next-Buffer object (for look ahead read) */
Buffer *save; /**< Temporary buffer to backup overflow data */
byte *xb; /**< Temporary byte buffer for reading/writing data */
uint8_t is_buffer; /**< Set to 1 if the backend is a Buffer */
uint8_t eof; /**< Set to 1 if EOF reached */
uint8_t err; /**< Set to 1 if an error occured */
@@ -404,31 +404,28 @@ void final(const char * fmt, ...);
/*** ./gencffi.pl: from ../../include/pcp/context.h:96 */
void ptx_dump(PCPCTX *ptx);
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */
size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubkey_t *p, int signcrypt, int anon);
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */
size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, int havehead, pcp_rec_t *recsign);
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */
size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify, int anon);
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */
size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify);
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */
int pcp_checksum(PCPCTX *ptx, Pcpstream *in, byte *checksum, byte *key, size_t keylen);
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */
pcp_rec_t *pcp_rec_new(byte *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_t *pub);
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */
void pcp_rec_free(pcp_rec_t *r);
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */
byte *_gen_ctr_nonce(uint64_t ctr);
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:351 */
/*** ./gencffi.pl: from ../../include/pcp/crypto.h:354 */
uint64_t _get_nonce_ctr(byte *nonce);
/*** ./gencffi.pl: from ../../include/pcp/ed.h:202 */
@@ -467,81 +464,90 @@ char *pcp_get_passphrase(char *prompt);
/*** ./gencffi.pl: from ../../include/pcp/jenhash.h:25 */
unsigned jen_hash ( unsigned char *k, unsigned length, unsigned initval );
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_key_t *pcpkey_new ();
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *epk);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
char *pcppubkey_get_art(pcp_pubkey_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
char *pcpkey_get_art(pcp_key_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_pubkey_t *pcpkey_pub_from_secret(pcp_key_t *key);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
char *pcp_getkeyid(pcp_key_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
char *pcp_getpubkeyid(pcp_pubkey_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
byte *pcppubkey_getchecksum(pcp_pubkey_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
byte *pcpkey_getchecksum(pcp_key_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_key_t * key2be(pcp_key_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_key_t *key2native(pcp_key_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_pubkey_t * pubkey2be(pcp_pubkey_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
byte * pcp_gennonce();
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
void pcp_seckeyblob(Buffer *b, pcp_key_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
Buffer *pcp_keyblob(void *k, int type);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_key_t *pcp_blob2key(Buffer *b);
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
pcp_pubkey_t *pcp_blob2pubkey(Buffer *b);
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
void pcp_dumpkey(pcp_key_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
void pcp_dumppubkey(pcp_pubkey_t *k);
/*** ./gencffi.pl: from ../../include/pcp/key.h:314 */
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
void pcpkey_setowner(pcp_key_t *key, char *owner, char *mail);
/*** ./gencffi.pl: from ../../include/pcp/key.h:324 */
double pcp_getentropy(char *source);
/*** ./gencffi.pl: from ../../include/pcp/keyhash.h:153 */
void pcphash_del(PCPCTX *ptx, void *key, int type);
@@ -569,19 +575,16 @@ int pcphash_countpub(PCPCTX *ptx);
/*** ./gencffi.pl: from ../../include/pcp/keyhash.h:153 */
pcp_keysig_t *pcphash_keysigexists(PCPCTX *ptx, char *id);
/*** ./gencffi.pl: from ../../include/pcp/keysig.h:52 */
pcp_keysig_t *keysig2be(pcp_keysig_t *s);
/*** ./gencffi.pl: from ../../include/pcp/keysig.h:50 */
void pcp_keysig2blob(Buffer *b, pcp_keysig_t *s);
/*** ./gencffi.pl: from ../../include/pcp/keysig.h:52 */
pcp_keysig_t *keysig2native(pcp_keysig_t *s);
/*** ./gencffi.pl: from ../../include/pcp/keysig.h:50 */
Buffer *pcp_keysigblob(pcp_keysig_t *s);
/*** ./gencffi.pl: from ../../include/pcp/keysig.h:52 */
Buffer *pcp_keysig2blob(pcp_keysig_t *s);
/*** ./gencffi.pl: from ../../include/pcp/keysig.h:50 */
pcp_keysig_t *pcp_blob2keysig(Buffer *blob);
/*** ./gencffi.pl: from ../../include/pcp/keysig.h:52 */
pcp_keysig_t *pcp_keysig_new(Buffer *blob);
/*** ./gencffi.pl: from ../../include/pcp/keysig.h:52 */
/*** ./gencffi.pl: from ../../include/pcp/keysig.h:50 */
void pcp_dumpkeysig(pcp_keysig_t *s);
/*** ./gencffi.pl: from ../../include/pcp/mem.h:58 */
@@ -605,61 +608,61 @@ void ucfree(void *d, size_t len);
/*** ./gencffi.pl: from ../../include/pcp/mem.h:58 */
void sfree(void *d);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
Buffer *pcp_export_pbp_pub(pcp_key_t *sk);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig, size_t siglen);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce, byte *cipher, size_t clen);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
json_t *pcp_sk2json(pcp_key_t *sk, byte *sig,size_t siglen);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
json_t *pcp_pk2json(pcp_pubkey_t *pk);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
pcp_ks_bundle_t *pcp_import_pub_json(PCPCTX *ptx, byte *raw, size_t rawsize);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
Buffer *pcp_import_secret_json(PCPCTX *ptx, Buffer *json);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
pcp_ks_bundle_t *pcp_import_binpub(PCPCTX *ptx, byte *raw, size_t rawsize);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphrase);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk);
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:188 */
/*** ./gencffi.pl: from ../../include/pcp/mgmt.h:193 */
int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader);
/*** ./gencffi.pl: from ../../include/pcp/pcpstream.h:291 */
@@ -740,27 +743,51 @@ int ps_readline(Pcpstream *stream, Buffer *line);
/*** ./gencffi.pl: from ../../include/pcp/randomart.h:54 */
char *key_fingerprint_randomart(unsigned char *dgst_raw, unsigned int dgst_raw_len);
/*** ./gencffi.pl: from ../../include/pcp/readpass.h:69 */
int pcp_readpass_fromprog(PCPCTX *ptx, char **passwd, const char *askpass);
/*** ./gencffi.pl: from ../../include/pcp/scrypt.h:42 */
byte * pcp_scrypt(PCPCTX *ptx, char *passwd, size_t passwdlen, byte *nonce, size_t noncelen);
/*** ./gencffi.pl: from ../../include/pcp/util.h:120 */
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
char *_lc(char *in);
/*** ./gencffi.pl: from ../../include/pcp/util.h:120 */
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
long int _findoffset(byte *bin, size_t binlen, char *sigstart, size_t hlen);
/*** ./gencffi.pl: from ../../include/pcp/util.h:120 */
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
void _xorbuf(byte *iv, byte *buf, size_t xlen);
/*** ./gencffi.pl: from ../../include/pcp/util.h:120 */
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
void _dump(char *n, byte *d, size_t s);
/*** ./gencffi.pl: from ../../include/pcp/util.h:120 */
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
char *_bin2hex(byte *bin, size_t len);
/*** ./gencffi.pl: from ../../include/pcp/util.h:120 */
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
size_t _hex2bin(const char *hex_str, unsigned char *byte_array, size_t byte_array_max);
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
int cst_time_memcmp(const void *m1, const void *m2, size_t n);
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
uint64_t _wireto64(byte *data);
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
uint32_t _wireto32(byte *data);
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
uint16_t _wireto16(byte *data);
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
void _64towire(uint64_t i, byte *data);
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
void _32towire(uint32_t i, byte *data);
/*** ./gencffi.pl: from ../../include/pcp/util.h:142 */
void _16towire(uint16_t i, byte *data);
/*** ./gencffi.pl: from ../../include/pcp/vault.h:230 */
vault_t *pcpvault_init(PCPCTX *ptx, char *filename);
@@ -866,149 +893,145 @@ uint8_t *zmq_z85_decode (uint8_t *dest, char *string);
/*** ./gencffi.pl: from ../../include/pcp/zmq_z85.h:31 */
char *zmq_z85_encode (char *dest, uint8_t *data, size_t size);'''
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_FORMAT_PBP = 2
# ./gencffi.pl: from ../../include/pcp/defines.h:172
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_ASYM_CIPHER = 5
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_SIG_CIPHER = 0x23
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_PK_HEADER = "----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_HASH_CIPHER = 0x22
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_HASH_NAME = "BLAKE2"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_CRYPTO_ADD = (32 - 16)
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_ASYM_CIPHER_SIG = 24
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_SIG_SUB_KEYFLAGS = 27
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_SIG_SUB_NOTATION = 20
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_VAULT_ID = 14
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_SK_HEADER = "----- BEGIN ED25519-CURVE29915 PRIVATE KEY -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_ENFILE_HEADER = "----- BEGIN PCP ENCRYPTED FILE -----\r\n"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_SIG_HEADER = "----- BEGIN ED25519 SIGNED MESSAGE -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_SIGPREFIX = "\nnacl-"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_ZFILE_FOOTER = "----- END Z85 ENCODED FILE -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_SK_FOOTER = "----- END ED25519-CURVE29915 PRIVATE KEY -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_SIG_END = "----- END ED25519 SIGNATURE -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_RFC_CIPHER = 0x21
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_ENCRYPT_MAC = 56
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_ME = "Pretty Curved Privacy"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_ASYM_CIPHER_ANON = 6
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_ENFILE_FOOTER = "\r\n----- END PCP ENCRYPTED FILE -----\r\n"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_SIG_SUB_CTIME = 2
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_SIG_START = "----- BEGIN ED25519 SIGNATURE -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_ZFILE_HEADER = "----- BEGIN Z85 ENCODED FILE -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_SIG_SUB_SIGEXPIRE = 3
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_SIG_CIPHER_NAME = "ED25519"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_PK_CIPHER = 0x21
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_PK_FOOTER = "----- END ED25519-CURVE29915 PUBLIC KEY -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_SIG_SUB_KEYEXPIRE = 9
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_FORMAT_NATIVE = 1
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PCP_SYM_CIPHER = 23
# ./gencffi.pl: from ../../include/pcp/defines.h:172
EXP_PK_CIPHER_NAME = "CURVE25519-ED25519-POLY1305-SALSA20"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
PBP_COMPAT_SALT = "qa~t](84z<1t<1oz:ik.@IRNyhG=8q(on9}4#!/_h#a7wqK{Nt$T?W>,mt8NqYq&6U<GB1$,<$j>,rSYI2GRDd:Bcm"
# ./gencffi.pl: from ../../include/pcp/defines.h:172
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_BLOCK_SIZE = 32 * 1024
# ./gencffi.pl: from ../../include/pcp/defines.h:172
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_PK_HEADER = "----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SK_FOOTER = "----- END ED25519-CURVE29915 PRIVATE KEY -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_ENFILE_HEADER = "----- BEGIN PCP ENCRYPTED FILE -----\r\n"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_FORMAT_NATIVE = 1
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PBP_COMPAT_SALT = "qa~t](84z<1t<1oz:ik.@IRNyhG=8q(on9}4#!/_h#a7wqK{Nt$T?W>,mt8NqYq&6U<GB1$,<$j>,rSYI2GRDd:Bcm"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_HASH_CIPHER = 0x22
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_HASH_NAME = "BLAKE2"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SIG_SUB_NOTATION = 20
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SIG_CIPHER_NAME = "ED25519"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SIG_CIPHER = 0x23
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_ZFILE_HEADER = "----- BEGIN Z85 ENCODED FILE -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_SIG_END = "----- END ED25519 SIGNATURE -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_PK_CIPHER = 0x21
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_RFC_CIPHER = 0x21
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_ASYM_CIPHER_ANON = 6
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_ENFILE_FOOTER = "\r\n----- END PCP ENCRYPTED FILE -----\r\n"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_SYM_CIPHER = 23
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SIG_TYPE = 0x1F
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SIG_SUB_KEYFLAGS = 27
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SK_HEADER = "----- BEGIN ED25519-CURVE29915 PRIVATE KEY -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_SIGPREFIX = "\nnacl-"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_ME = "Pretty Curved Privacy"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_ZFILE_FOOTER = "----- END Z85 ENCODED FILE -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SIG_SUB_SIGEXPIRE = 3
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SIG_SUB_CTIME = 2
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_PK_FOOTER = "----- END ED25519-CURVE29915 PUBLIC KEY -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_VAULT_ID = 14
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_ASYM_CIPHER_ANON_SIG = 7
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_SIG_HEADER = "----- BEGIN ED25519 SIGNED MESSAGE -----"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_ASYM_CIPHER_SIG = 24
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_PK_CIPHER_NAME = "CURVE25519-ED25519-POLY1305-SALSA20"
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_FORMAT_PBP = 2
# ./gencffi.pl: from ../../include/pcp/defines.h:185
EXP_SIG_SUB_KEYEXPIRE = 9
# ./gencffi.pl: from ../../include/pcp/defines.h:185
PCP_SIG_START = "----- BEGIN ED25519 SIGNATURE -----"

View File

@@ -1,435 +0,0 @@
# -*-sh-*-
#
# This file is part of Pretty Curved Privacy (pcp1).
#
# Copyright (C) 2013-2015 T.Linden.
#
# 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/>.
#
# You can contact me by mail: <tlinden AT cpan DOT org>.
#
AC_PREREQ(2.61)
define([pcpversion], esyscmd([sh -c "cat VERSION"]))dnl
AC_INIT([pcp], [pcpversion], [pcp@daemon.de])
#AC_INIT(pcp, `cat VERSION`)
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_MACRO_DIR(config)
AC_CONFIG_HEADER(include/pcp/config.h)
AM_INIT_AUTOMAKE([subdir-objects])
LT_INIT
ORIG_CFLAGS="${CFLAGS:-none}"
# Checks for programs
AC_PROG_CXX
AC_PROG_CXXCPP
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AC_PROG_SED
AC_PROG_AWK
AC_PROG_INSTALL
# remove flags set by AC_PROG_CC (duplicates and/or invalid for clang)
# FIXME: why did I do this?!
#CFLAGS=""
#CXXFLAGS=""
# Host speciffic checks
AC_CANONICAL_HOST
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(errno.h err.h stdlib.h string.h unistd.h stdio.h getopt.h\
limits.h stddef.h stdint.h sys/types.h sys/stat.h endian.h \
sys/endian.h termios.h arpa/inet.h netinet/in.h wctype.h)
AC_TYPE_SIZE_T
# Checks for library functions.
AC_CHECK_FUNCS( \
arc4random_buf \
arc4random \
fread \
fopen \
free \
fwrite \
fseek \
ftruncate \
fprintf \
isatty \
malloc \
memset \
memcpy \
mmap \
perror \
posix_memalign \
setrlimit \
strnlen \
strnstr \
strlen \
strtol \
sizeof \
tcgetattr \
umask \
towlower \
getopt_long \
vasprintf
)
AC_MSG_CHECKING([for be32toh])
AC_TRY_LINK([
#include "libpcp/pcp/config.h"
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#endif
#ifdef HAVE_SYS_ENDIAN_H
#include <sys/endian.h>
#endif
], [
(void)be32toh(0);
], [AC_MSG_RESULT([no])], [
AC_DEFINE(HAVE_BE32TOH,, Define if be32toh() is available)
AC_MSG_RESULT([yes])
])
AC_MSG_CHECKING([for htobe32])
AC_TRY_LINK([
#include "libpcp/pcp/config.h"
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#endif
#ifdef HAVE_SYS_ENDIAN_H
#include <sys/endian.h>
#endif
], [
(void)htobe32(0);
], [AC_MSG_RESULT([no])], [
AC_DEFINE(HAVE_HTOBE32,, Define if htobe32() is available)
AC_MSG_RESULT([yes])
])
cross_compile="no"
AC_MSG_CHECKING([compiler and flags for sanity])
AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]], [[ exit(0); ]])],
[ AC_MSG_RESULT([yes]) ],
[
AC_MSG_RESULT([no])
AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***])
],
[
AC_MSG_WARN([cross compiling: not checking compiler sanity])
[cross_compile="yes"]
]
)
_havenacl=no
_ldlib=""
_have_json=no
AC_ARG_WITH([libsodium],
[AS_HELP_STRING([--with-libsodium],
[Specify libsodium prefix])],
[search_libsodium="yes"],
[])
if test "x$search_libsodium" = "xyes"; then
if test -r "${with_libsodium}/include/sodium.h"; then
CFLAGS="-I${with_libsodium}/include ${CFLAGS}"
LDFLAGS="-L${with_libsodium}/lib ${LDFLAGS}"
_havenacl=yes
_ldlib="${with_libsodium}/lib"
fi
fi
AC_ARG_WITH([libsodium-include-dir],
[AS_HELP_STRING([--with-libsodium-include-dir],
[Specify libsodium include prefix])],
[search_libsodium_include="yes"],
[])
if test "x$search_libsodium_include" = "xyes"; then
if test -r "${with_libsodium_include_dir}/sodium.h"; then
CFLAGS="-I${with_libsodium_include_dir} ${CFLAGS}"
_havenacl=yes
fi
fi
AC_ARG_WITH([libsodium_lib_dir],
[AS_HELP_STRING([--with-libsodium-lib-dir],
[Specify libsodium library prefix])],
[search_libsodium_lib="yes"],
[])
if test "x$search_libsodium_lib" = "xyes"; then
if test -r "${with_libsodium_lib_dir}/libsodium.dylib" -o -r "${with_libsodium_lib_dir}/libsodium.so" -o -r "${with_libsodium_lib_dir}/libsodium.a"; then
LDFLAGS="-L${with_libsodium_lib_dir} ${LDFLAGS}"
_havenacl=yes
_ldlib="${with_libsodium_lib_dir}"
fi
fi
if test "x${_havenacl}" = "xno"; then
AC_MSG_CHECKING([pkg-config for libsodium])
if pkg-config --exists libsodium; then
# found it
LDFLAGS="`pkg-config --libs libsodium` ${LDFLAGS}"
CFLAGS="`pkg-config --cflags libsodium` ${CFLAGS}"
_ldlib=`pkg-config --libs libsodium | cut -d ' ' -f 1 | cut -d L -f 2`
_havenacl=yes
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
fi
if test "x${_havenacl}" != "xno" -a "x$cross_compile" = "xno"; then
LIBS="-lsodium" # gcc
export LDFLAGS="$LDFLAGS"
export CFLAGS="$CFLAGS"
export LIBS="$LIBS"
AC_MSG_CHECKING([libsodium version compatible])
AC_RUN_IFELSE([
AC_LANG_PROGRAM([[
#include <sodium.h>
]],[[
if (sodium_library_version_major() >= 7) { exit(0); }
else { exit(1); }
]])],
[
AC_MSG_RESULT([yes])
],
[
AC_MSG_ERROR([no, libsodium too old. please update your libsodium installation. or maybe the path in "$LDFLAGS" is not in LD_LIBRARY_PATH?])
]
)
fi
AC_ARG_WITH([json],
[AS_HELP_STRING([--with-json],
[enable JSON support])],
[search_json="yes"],
[])
if test "x$search_json" = "xyes"; then
# use pkg only
# FIXME: search
_have_json="yes"
LDFLAGS="$LDFLAGS -ljansson"
CFLAGS="$CFLAGS -DHAVE_JSON=1"
fi
AM_CONDITIONAL([BUILDJSON], [test "x$_have_json" = "xyes"])
# Check for some target-specific stuff
case "$host" in
*aix*)
# libm is required as well
CFLAGS="$CFLAGS -D_AIX_SOURCE=1"
LDFLAGS="$LDFLAGS -lm"
;;
*-*-android*) ;;
*-*-cygwin*) ;;
*-*-dgux*) ;;
*-*-darwin*) ;;
*-*-dragonfly*) ;;
*-*-haiku*) ;;
*-*-hpux*) ;;
*-*-irix5*) ;;
*-*-irix6*) ;;
*-*-k*bsd*-gnu | *-*-kopensolaris*-gnu) ;;
*-*-linux*) ;;
*-*-netbsd*) ;;
*-*-freebsd*)
# ports install to /usr/local by default, check
if test -d "/usr/local/lib" -a -d "/usr/local/include"; then
CFLAGS="$CFLAGS -I/usr/local/include"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
fi
;;
*-*-bsdi*) ;;
*-next-*) ;;
*-*-openbsd*) ;;
*-*-solaris*) ;;
*-*-sunos4*) ;;
*-ncr-sysv*) ;;
*-sni-sysv*) ;;
*-*-sysv4.2*) ;;
*-*-sysv5*) ;;
*-*-sysv*) ;;
*-*-sco*) ;;
*-*-unicos*) ;;
*-dec-osf*) ;;
*-*-nto-qnx*) ;;
*-*-ultrix*) ;;
*-*-lynxos) ;;
esac
AC_CHECK_LIB(sodium, sodium_init, , [AC_MSG_ERROR([cannot link with -lsodium, install libsodium.])])
if test -n "$_ldlib"; then
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${_ldlib}"
fi
if test "$cross_compile" = "no"; then
AC_MSG_CHECKING([is libsodium compiled correctly])
AC_RUN_IFELSE([
AC_LANG_PROGRAM([[
#include <sodium.h>
#include <stdlib.h>
#if crypto_box_PUBLICKEYBYTES != 32 || crypto_box_SECRETKEYBYTES != 32 || crypto_sign_PUBLICKEYBYTES != 32 || crypto_sign_PUBLICKEYBYTES != 32
# error "libsodium not built correctly"
#endif
]],[[exit(0);]])],
[
AC_MSG_RESULT([yes])
],
[
AC_MSG_ERROR([no. please check your libsodium installation, consider re-installing])
]
)
fi
if test "$cross_compile" = "no"; then
# check endianess
# program returns 0 on little and 1 on big endian systems
AC_MSG_CHECKING([are we on a big endian system])
AC_RUN_IFELSE([
AC_LANG_PROGRAM([[]],[[long one= 1; exit(!(*((char *)(&one)))); ]])],
[
AC_MSG_RESULT([no])
bigendian="no"
],
[
AC_MSG_RESULT([yes])
bigendian="yes"
]
)
fi
if test "x$bigendian" = "xyes"; then
CFLAGS="$CFLAGS -D__CPU_IS_BIG_ENDIAN=1"
fi
# prepare FLAGS
CFLAGS="$CFLAGS -Werror -Wextra -Wall"
AC_ARG_ENABLE([debug],
AS_HELP_STRING([--disable-debug], [Disable debugging]))
AS_IF([test "x$enable_debug" != "xno"], [
CFLAGS="$CFLAGS -g -DDEBUG"
enable_debug="yes"
])
AC_ARG_ENABLE([optimize],
AS_HELP_STRING([--disable-optimize], [Disable optimization]))
AS_IF([test "x$enable_optimize" != "xno"], [
case $enable_optimize in
-O*)
CFLAGS="$CFLAGS $enable_optimize"
enable_optimize="$enable_optimize"
;;
*)
CFLAGS="$CFLAGS -O2"
enable_optimize="-O2"
;;
esac
])
CXXFLAGS="$CFLAGS"
# conditionals for bindings and stuff
# c++
AC_ARG_ENABLE([cpp-binding],
[AS_HELP_STRING([--disable-cpp-binding],
[Disable C++ binding])],
)
AS_IF([test "x$enable_cpp_binding" != "xno"], [
enable_cpp_binding=yes
])
AM_CONDITIONAL([BUILDCPP], [test "x$enable_cpp_binding" != "xno"])
# py
AC_ARG_ENABLE([python-binding],
[AS_HELP_STRING([--enable-python-binding],
[Enable python binding])
],
[python="yes"],
[])
if test "x$python" = "xyes"; then
if ! python -c "import cffi" > /dev/null 2>&1; then
python="no"
AC_MSG_ERROR([python or cffi is not installed])
fi
else
python="no"
fi
AM_CONDITIONAL([BUILDPY], [test "x$python" = "xyes"])
AC_SUBST(PACKAGE_VERSION)
# Specify output files
AC_CONFIG_FILES([Makefile include/Makefile libpcp/Makefile src/Makefile man/Makefile \
tests/Makefile libpcp/libpcp1.pc bindings/cpp/Makefile bindings/py/Makefile])
AC_OUTPUT
AC_MSG_RESULT([
Build configured for $PACKAGE $VERSION:
CC: ${CC}
CFLAGS: ${CFLAGS}
CXX: ${CXX}
CXXFLAGS: ${CXXFLAGS}
LDFLAGS: ${LDFLAGS}
LIBS: ${LIBS}
debug: ${enable_debug}
optimize: ${enable_optimize}
prefix: ${prefix}
libdir: ${libdir}
includedir: ${includedir}
target platform: ${host}
big endian cpu: ${bigendian}
cross compile: ${cross_compile}
build python binding: ${python}
build c++ binding: ${enable_cpp_binding}
json support ${_have_json}
Type 'make' to build, 'make install' to install.
To execute unit tests, type 'make test'.
])

View File

@@ -1,38 +0,0 @@
#
# This file is part of Pretty Curved Privacy (pcp1).
#
# Copyright (C) 2013 T.Linden.
#
# 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/>.
#
# You can contact me by mail: <tlinden AT cpan DOT org>.
#
AM_CFLAGS = -I../include/pcp -Iscrypt/util
lib_LTLIBRARIES = libpcp1.la
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libpcp1.pc
libpcp1_la_SOURCES = platform.c mem.c version.c \
context.c z85.c zmq_z85.c key.c randomart.c \
vault.c jenhash.c \
crypto.c ed.c keyhash.c scrypt.c \
util.c buffer.c mgmt.c keysig.c pcpstream.c
include_HEADERS = ../include/pcp.h
libpcp1_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -62,7 +62,7 @@ void buffer_free(Buffer *b) {
if(b->allocated == 1) {
/* free the underlying data pointer only if we allocated it */
if(b->end > 0) {
buffer_clear(b);
buffer_clear(b);
}
free(b->buf);
b->allocated = 0;
@@ -95,7 +95,7 @@ void buffer_add_str(Buffer *b, const char * fmt, ...) {
if(vasprintf(&dst, fmt, ap) >= 0) {
if(b->end > 0)
b->end--;
buffer_add(b, dst, strlen(dst)+1);
buffer_add(b, dst, strlen(dst));
}
va_end(ap);
free(dst);
@@ -132,7 +132,7 @@ byte *buffer_get(Buffer *b) {
size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
if(len > b->end - b->offset) {
final("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
b->name, len, b->end - b->offset, b->offset);
b->name, len, b->end - b->offset, b->offset);
}
else if(len == 0) {
/* FIXME: check how this happens */
@@ -148,7 +148,7 @@ size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
size_t buffer_fwd_offset(Buffer *b, size_t fwdby) {
if(fwdby > b->end - b->offset) {
final("[buffer %s] attempt to set offset %ld bytes forward data from buffer with %ld bytes left at offset %ld\n",
b->name, fwdby, b->end - b->offset, b->offset);
b->name, fwdby, b->end - b->offset, b->offset);
}
else if(fwdby == 0) {
return 0;
@@ -161,7 +161,7 @@ size_t buffer_fwd_offset(Buffer *b, size_t fwdby) {
size_t buffer_get_chunk_tobuf(Buffer *b, Buffer *dst, size_t len) {
if(len > b->end - b->offset) {
final("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
b->name, len, b->end - b->offset, b->offset);
b->name, len, b->end - b->offset, b->offset);
}
else if(len == 0) {
/* FIXME: check how this happens */
@@ -221,30 +221,27 @@ uint64_t buffer_get64(Buffer *b) {
}
uint16_t buffer_get16na(Buffer *b) {
uint16_t i;
if(buffer_get_chunk(b, &i, 2) > 0) {
i = be16toh(i);
return i;
uint8_t bin[2];
if(buffer_get_chunk(b, bin, 2) > 0) {
return _wireto16(bin);
}
else
return 0;
}
uint32_t buffer_get32na(Buffer *b) {
uint32_t i;
if(buffer_get_chunk(b, &i, 4) > 0) {
i = be32toh(i);
return i;
uint8_t bin[4];
if(buffer_get_chunk(b, bin, 4) > 0) {
return _wireto32(bin);
}
else
return 0;
}
uint64_t buffer_get64na(Buffer *b) {
uint64_t i;
if(buffer_get_chunk(b, &i, 8) > 0) {
i = be64toh(i);
return i;
uint8_t bin[8];
if(buffer_get_chunk(b, bin, 8) > 0) {
return _wireto64(bin);
}
else
return 0;
@@ -362,19 +359,19 @@ void buffer_add64(Buffer *b, uint64_t v) {
}
void buffer_add16be(Buffer *b, uint16_t v) {
uint16_t e = v;
e = htobe16(e);
buffer_add(b, &e, 2);
uint8_t bin[2];
_16towire(v, bin);
buffer_add(b, bin, 2);
}
void buffer_add32be(Buffer *b, uint32_t v) {
uint32_t e = v;
e = htobe32(e);
buffer_add(b, &e, 4);
uint8_t bin[4];
_32towire(v, bin);
buffer_add(b, bin, 4);
}
void buffer_add64be(Buffer *b, uint64_t v) {
uint64_t e = v;
e = htobe64(e);
buffer_add(b, &e, 8);
uint8_t bin[8];
_64towire(v, bin);
buffer_add(b, bin, 8);
}

17
libpcp/config.h.in Normal file
View File

@@ -0,0 +1,17 @@
/* platform.h.in. Generated from configure.ac by autoheader. */
#mesondefine HAVE_SODIUM
#mesondefine HAVE_JSON
#mesondefine HAVE_GETOPT
#mesondefine HAVE_GETOPT_LONG
#mesondefine HAVE_SETRLIMIT
#mesondefine HAVE_VASPRINTF
#mesondefine HAVE_STRNLEN
#define PACKAGE "pcp"
#define VERSION "@VERSION@"
/* Define to empty if `const' does not conform to ANSI C. */
#undef const

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -43,7 +43,10 @@ PCPCTX *ptx_new() {
p->pcppubkey_hash = NULL;
p->pcpkeysig_hash = NULL;
sodium_init();
if(sodium_init() == -1) {
perror("failed to initialize libsodium");
exit(1);
}
return p;
}

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -24,11 +24,10 @@
/* asym encr */
byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
byte *message, size_t messagesize,
size_t *csize) {
byte *message, size_t messagesize,
size_t *csize) {
byte *nonce = pcp_gennonce();
@@ -44,14 +43,14 @@ byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
}
/* put nonce and cipher together */
byte *combined = ucmalloc(es + crypto_secretbox_NONCEBYTES);
memcpy(combined, nonce, crypto_secretbox_NONCEBYTES);
memcpy(&combined[crypto_secretbox_NONCEBYTES], cipher, es);
byte *combined = ucmalloc(es + LNONCE);
memcpy(combined, nonce, LNONCE);
memcpy(&combined[LNONCE], cipher, es);
free(cipher);
free(nonce);
*csize = es + crypto_secretbox_NONCEBYTES;
*csize = es + LNONCE;
return combined;
@@ -66,21 +65,21 @@ byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
/* asym decr */
byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
byte *cipher, size_t ciphersize,
size_t *dsize) {
byte *cipher, size_t ciphersize,
size_t *dsize) {
byte *message = NULL;
byte *nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
byte *cipheronly = ucmalloc(ciphersize - crypto_secretbox_NONCEBYTES);
byte *nonce = ucmalloc(LNONCE);
byte *cipheronly = ucmalloc(ciphersize - LNONCE);
memcpy(nonce, cipher, crypto_secretbox_NONCEBYTES);
memcpy(cipheronly, &cipher[crypto_secretbox_NONCEBYTES],
ciphersize - crypto_secretbox_NONCEBYTES);
memcpy(nonce, cipher, LNONCE);
memcpy(cipheronly, &cipher[LNONCE],
ciphersize - LNONCE);
message = ucmalloc(ciphersize - crypto_secretbox_NONCEBYTES - crypto_box_MACBYTES);
if(crypto_box_open_easy(message, cipheronly, ciphersize - crypto_secretbox_NONCEBYTES,
nonce, pub->pub, secret->secret) != 0) {
message = ucmalloc(ciphersize - LNONCE - crypto_box_MACBYTES);
if(crypto_box_open_easy(message, cipheronly, ciphersize - LNONCE,
nonce, pub->pub, secret->secret) != 0) {
fatal(ptx, "failed to decrypt message!\n");
goto errbed;
}
@@ -90,7 +89,7 @@ byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
/* resulting size: */
/* ciphersize - crypto_secretbox_ZEROBYTES */
*dsize = ciphersize - crypto_secretbox_NONCEBYTES - PCP_CRYPTO_ADD;
*dsize = ciphersize - LNONCE - LMAC;
return message;
errbed:
@@ -104,29 +103,28 @@ byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
/* sym encr */
size_t pcp_sodium_mac(byte **cipher,
byte *cleartext,
size_t clearsize,
byte *nonce,
byte *key) {
byte *cleartext,
size_t clearsize,
byte *nonce,
byte *key) {
*cipher = ucmalloc(clearsize + crypto_secretbox_MACBYTES);
*cipher = ucmalloc(clearsize + LMAC);
crypto_secretbox_easy(*cipher, cleartext, clearsize, nonce, key);
return clearsize + crypto_secretbox_MACBYTES;
return clearsize + LMAC;
}
/* sym decr */
int pcp_sodium_verify_mac(byte **cleartext, byte* message,
size_t messagesize, byte *nonce,
byte *key) {
size_t messagesize, byte *nonce,
byte *key) {
*cleartext = ucmalloc(messagesize - crypto_secretbox_MACBYTES);
return crypto_secretbox_open_easy(*cleartext, message, messagesize, nonce, key);
}
size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify, int anon) {
pcp_pubkey_t *cur = NULL;
pcp_pubkey_t *cur = NULL, *fromsec = NULL;
byte *reccipher = NULL;
int recmatch, self;
uint32_t lenrec;
@@ -147,31 +145,41 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t
cur_bufsize = ps_read(in, head, 1); /* fread(head, 1, 1, in); */
if(cur_bufsize == 1 && !ps_end(in) && !ps_err(in)) {
if(head[0] == PCP_SYM_CIPHER) {
if(symkey != NULL)
self = 1;
else {
fatal(ptx, "Input is symetrically encrypted but no key have been specified (lib usage failure)\n");
goto errdef1;
}
if(symkey != NULL)
self = 1;
else {
fatal(ptx, "Input is symetrically encrypted but no key have been specified (lib usage failure)\n");
goto errdef1;
}
}
else if(head[0] == PCP_ASYM_CIPHER_ANON) {
self = 0;
anon = 1;
self = 0;
anon = 1;
}
else if(head[0] == PCP_ASYM_CIPHER_ANON_SIG) {
self = 0;
anon = 1;
verify = 1;
}
else if(head[0] == PCP_ASYM_CIPHER) {
self = 0;
self = 0;
}
else if(head[0] == PCP_ASYM_CIPHER_SIG) {
self = 0;
verify = 1;
self = 0;
verify = 1;
}
else {
fatal(ptx, "Unknown file header (got: %02x)\n", head[0]);
goto errdef1;
fatal(ptx, "Unknown file header (got: %02x)\n", head[0]);
goto errdef1;
}
}
}
if(ptx->verbose) {
fprintf(stderr, "crypto.c: header <= self: %d, anon: %d, verify:%d\n",
self, anon, verify);
}
if(self) {
/* just decrypt symetrically and go outa here */
return pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
@@ -185,81 +193,119 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t
fatal(ptx, "Error: input file doesn't contain senders public key\n");
goto errdef1;
}
if(ptx->verbose) {
fprintf(stderr, "crypto.c: <= sender anon pub key:\n");
pcp_dumppubkey(senderpub);
}
}
/* step 3, check len recipients */
cur_bufsize = ps_read(in, &lenrec, 4); /* fread(&lenrec, 1, 4, in); */
byte li[4];
cur_bufsize = ps_read(in, li, 4); /* fread(&lenrec, 1, 4, in); */
if(cur_bufsize != 4 && !ps_end(in) && !ps_err(in)) {
fatal(ptx, "Error: input file doesn't contain recipient count\n");
goto errdef1;
}
lenrec = be32toh(lenrec);
lenrec = _wireto32(li);
if (ptx->verbose) {
fprintf(stderr, "crypto.c: input is encrypted for %ld recipients\n", (long int)lenrec);
}
if(verify) {
reccipher = ucmalloc(lenrec * PCP_ASYM_RECIPIENT_SIZE);
}
/* step 4, fetch recipient list and try to decrypt it for us */
rec_buf = ucmalloc(PCP_ASYM_RECIPIENT_SIZE);
for(nrec=0; nrec<lenrec; nrec++) {
cur_bufsize = ps_read(in, rec_buf, PCP_ASYM_RECIPIENT_SIZE);
if(cur_bufsize != PCP_ASYM_RECIPIENT_SIZE && !ps_end(in) && !ps_err(in)) {
fatal(ptx, "Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n",
cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
ucfree(rec_buf, PCP_ASYM_RECIPIENT_SIZE);
goto errdef1;
}
recmatch = 0;
if(ptx->verbose) {
fprintf(stderr, "crypto.c: <= rec_cipher:\n");
_dump("crypto.c: encrypted rec cipher", rec_buf, cur_bufsize);
}
if(anon) {
/* anonymous sender */
byte *recipient;
recipient = pcp_box_decrypt(ptx, s, senderpub, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
/* found a match */
recmatch = 1;
symkey = smalloc(crypto_secretbox_KEYBYTES);
memcpy(symkey, recipient, crypto_secretbox_KEYBYTES);
free(recipient);
ucfree(senderpub, sizeof(pcp_pubkey_t));
break;
/* found a match */
recmatch = 1;
symkey = smalloc(crypto_secretbox_KEYBYTES);
memcpy(symkey, recipient, crypto_secretbox_KEYBYTES);
free(recipient);
ucfree(senderpub, sizeof(pcp_pubkey_t));
if(verify) {
memcpy(reccipher, rec_buf, PCP_ASYM_RECIPIENT_SIZE);
}
nrec++; /* otherwise missing */
if(ptx->verbose) {
_dump("crypto.c: got anon symkey", symkey, crypto_secretbox_KEYBYTES);
}
break;
}
free(recipient);
}
else {
/* dig through our list of known public keys for a match */
pcphash_iteratepub(ptx, cur) {
byte *recipient;
recipient = pcp_box_decrypt(ptx, s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
/* found a match */
recmatch = 1;
symkey = smalloc(crypto_secretbox_KEYBYTES);
memcpy(symkey, recipient, crypto_secretbox_KEYBYTES);
free(recipient);
break;
}
free(recipient);
byte *recipient;
recipient = pcp_box_decrypt(ptx, s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
/* found a match */
recmatch = 1;
symkey = smalloc(crypto_secretbox_KEYBYTES);
memcpy(symkey, recipient, crypto_secretbox_KEYBYTES);
free(recipient);
if(ptx->verbose) {
fprintf(stderr, "crypto.c: matching pub key:\n");
pcp_dumppubkey(cur);
_dump("crypto.c: got recipient symkey", symkey, crypto_secretbox_KEYBYTES);
}
break;
}
free(recipient);
}
/* do the same with our secret keys, just in case the sender used -M */
if(recmatch == 0) {
pcp_key_t *k;
pcphash_iterate(ptx, k) {
cur = pcpkey_pub_from_secret(k);
byte *recipient;
recipient = pcp_box_decrypt(ptx, s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
/* found a match */
recmatch = 1;
symkey = smalloc(crypto_secretbox_KEYBYTES);
memcpy(symkey, recipient, crypto_secretbox_KEYBYTES);
free(recipient);
break;
}
}
pcp_key_t *k;
pcphash_iterate(ptx, k) {
if(fromsec != NULL)
ucfree(fromsec, sizeof(pcp_pubkey_t)); /* avoid overwrite of used mem */
fromsec = pcpkey_pub_from_secret(k);
byte *recipient;
recipient = pcp_box_decrypt(ptx, s, fromsec, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
/* found a match */
recmatch = 1;
symkey = smalloc(crypto_secretbox_KEYBYTES);
memcpy(symkey, recipient, crypto_secretbox_KEYBYTES);
free(recipient);
cur = fromsec;
if(ptx->verbose) {
_dump("crypto.c: got my own sec symkey", symkey, crypto_secretbox_KEYBYTES);
}
break;
}
}
}
}
if(verify) {
@@ -278,35 +324,40 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t
/* step 5, actually decrypt the file, finally */
if(verify) {
pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * PCP_ASYM_RECIPIENT_SIZE, NULL, cur);
size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, rec);
pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * (PCP_ASYM_RECIPIENT_SIZE), NULL, cur);
nrec = pcp_decrypt_stream_sym(ptx, in, out, symkey, rec);
pcp_rec_free(rec);
ucfree(reccipher, lenrec * PCP_ASYM_RECIPIENT_SIZE);
sfree(symkey);
return s;
}
else {
size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
sfree(symkey);
return s;
nrec = pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
}
if(fromsec != NULL)
ucfree(fromsec, sizeof(pcp_pubkey_t));
sfree(symkey);
return nrec;
errdef1:
if(fromsec != NULL)
ucfree(fromsec, sizeof(pcp_pubkey_t));
sfree(symkey);
return 0;
}
size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign, int anon) {
size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *secret,
pcp_key_t *signsecret, pcp_pubkey_t *p, int sign, int anon) {
byte *symkey;
int recipient_count;
byte *recipients_cipher;
pcp_pubkey_t *cur, *t;
size_t es;
int nrec;
uint32_t lenrec;
size_t rec_size, out_size;
byte head[1];
byte bo[4];
/*
6[1]|temp_keypair.pubkey|len(recipients)[4]|(recipients...)|(secretboxes...)
where recipients is a concatenated list of
@@ -317,22 +368,36 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t
/* A, generate sym key */
symkey = srmalloc(crypto_secretbox_KEYBYTES);
if(ptx->verbose) {
_dump("crypto.c: new symkey", symkey, crypto_secretbox_KEYBYTES);
}
/* B, encrypt it asymetrically for each recipient */
recipient_count = HASH_COUNT(p);
rec_size = PCP_ASYM_RECIPIENT_SIZE;
recipients_cipher = ucmalloc(rec_size * recipient_count);
nrec = 0;
if(ptx->verbose) {
fprintf(stderr, "crypto.c: async recipients: %d\n", recipient_count);
}
HASH_ITER(hh, p, cur, t) {
byte *rec_cipher;
rec_cipher = pcp_box_encrypt(ptx, s, cur, symkey, crypto_secretbox_KEYBYTES, &es);
rec_cipher = pcp_box_encrypt(ptx, secret, cur, symkey, crypto_secretbox_KEYBYTES, &es);
if(es != rec_size) {
fatal(ptx, "invalid rec_size, expected %dl, got %dl\n", rec_size, es);
if(rec_cipher != NULL)
free(rec_cipher);
free(rec_cipher);
goto errec1;
}
if(ptx->verbose) {
fprintf(stderr, "crypto.c: recipient pub key:\n");
pcp_dumppubkey(cur);
_dump("crypto.c: encrypted rec cipher", rec_cipher, rec_size);
}
/* put it into the recipient list, already includes the nonce */
memcpy(&recipients_cipher[nrec * rec_size], rec_cipher, rec_size);
nrec++;
@@ -340,14 +405,21 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t
}
/* step 1, file header */
if(sign)
head[0] = PCP_ASYM_CIPHER_SIG;
if(ptx->verbose) {
fprintf(stderr, "crypto.c: header => anon: %d, verify:%d\n",
anon, sign);
}
if(sign && anon)
head[0] = PCP_ASYM_CIPHER_ANON_SIG;
else if(sign)
head[0] = PCP_ASYM_CIPHER_SIG;
else if(anon)
head[0] = PCP_ASYM_CIPHER_ANON;
else
else
head[0] = PCP_ASYM_CIPHER;
ps_write(out, head, 1);
if(ps_err(out) != 0) {
fatal(ptx, "Failed to write encrypted output!\n");
goto errec1;
@@ -355,26 +427,25 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t
if(anon) {
/* step 2, sender's pubkey */
ps_write(out, s->pub, crypto_box_PUBLICKEYBYTES);
/*fwrite(s->pub, crypto_box_PUBLICKEYBYTES, 1, out); */
/* fprintf(stderr, "D: sender pub - %d\n", crypto_box_PUBLICKEYBYTES); */
ps_write(out, secret->pub, crypto_box_PUBLICKEYBYTES);
if(ps_err(out) != 0)
goto errec1;
if(ptx->verbose) {
fprintf(stderr, "crypto.c: => anon pub key:\n");
_dump("crypto.c: => anon pub key", secret->pub, 32);
}
}
/* step 3, len recipients, big endian */
lenrec = recipient_count;
lenrec = htobe32(lenrec);
ps_write(out, &lenrec, 4);
/* fwrite(&lenrec, 4, 1, out); */
/* fprintf(stderr, "D: %d recipients - 4\n", recipient_count); */
_32towire(recipient_count, bo);
ps_write(out, bo, 4);
if(ps_err(out) != 0)
goto errec1;
/* step 4, recipient list */
ps_write(out, recipients_cipher, rec_size * recipient_count);
/* fwrite(recipients_cipher, rec_size * recipient_count, 1, out); */
/* fprintf(stderr, "D: recipients - %ld * %d\n", rec_size, recipient_count); */
if(ps_err(out) != 0)
goto errec1;
@@ -383,7 +454,7 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t
/* step 5, actual encrypted data */
size_t sym_size = 0;
if(sign) {
pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, s, NULL);
pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, signsecret, NULL);
sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, rec);
pcp_rec_free(rec);
}
@@ -440,11 +511,13 @@ size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte *
if(havehead == 0) {
head[0] = PCP_SYM_CIPHER;
es = ps_write(out, head, 1);
/* es = fwrite(head, 1, 1, out); */
if(ps_err(out) != 0) {
fatal(ptx, "Failed to write encrypted output!\n");
return 0;
}
if(ptx->verbose) {
fprintf(stderr, "crypto.c: => header: self: 1\n");
}
}
/* 32k-Block-mode. */
@@ -458,15 +531,15 @@ size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte *
buf_nonce = _gen_ctr_nonce(ctr++);
es = pcp_sodium_mac(&buf_cipher, in_buf, cur_bufsize, buf_nonce, symkey);
ps_write(out, buf_nonce, crypto_secretbox_NONCEBYTES);
ps_write(out, buf_nonce, LNONCE);
ps_write(out, buf_cipher, es);
out_size += crypto_secretbox_NONCEBYTES + es;
out_size += LNONCE + es;
if(recsign != NULL)
crypto_generichash_update(st, buf_cipher, es);
ucfree(buf_nonce, crypto_secretbox_NONCEBYTES);
ucfree(buf_nonce, LNONCE);
free(buf_cipher);
}
@@ -479,26 +552,32 @@ size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte *
if(recsign != NULL) {
/* add encrypted recipient list to the hash */
crypto_generichash_update(st, recsign->cipher, recsign->ciphersize);
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
crypto_generichash_final(st, hash, LHASH);
/* generate the actual signature */
byte *signature = pcp_ed_sign(hash, crypto_generichash_BYTES_MAX, recsign->secret);
size_t siglen = crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
byte *signature = pcp_ed_sign(hash, LHASH, recsign->secret);
size_t siglen = LSIG + LHASH;
/* encrypt it as well */
buf_nonce = pcp_gennonce();
es = pcp_sodium_mac(&buf_cipher, signature, siglen, buf_nonce, symkey);
ps_write(out, buf_nonce, crypto_secretbox_NONCEBYTES);
ps_write(out, buf_nonce, LNONCE);
ps_write(out, buf_cipher, es);
if(ptx->verbose) {
_dump("crypto.c: => sig", signature, siglen);
_dump("crypto.c: => nonce", buf_nonce, LNONCE);
_dump("crypto.c: => enc sig", buf_cipher, es);
}
free(st);
free(hash);
ucfree(buf_nonce, crypto_secretbox_NONCEBYTES);
ucfree(buf_nonce, LNONCE);
free(buf_cipher);
ucfree(signature, siglen);
}
ucfree(in_buf, PCP_BLOCK_SIZE);
return out_size;
@@ -512,17 +591,18 @@ size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte *
return 0;
}
size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) {
size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out,
byte *symkey, pcp_rec_t *recverify) {
byte *buf_nonce;
byte *buf_cipher;
byte *buf_clear;
size_t out_size, cur_bufsize, es;
size_t ciphersize = (PCP_BLOCK_SIZE_IN) - crypto_secretbox_NONCEBYTES;
size_t ciphersize = (PCP_BLOCK_SIZE_IN) - LNONCE;
byte *in_buf = NULL;
uint64_t ctr, pastctr;
pastctr = 0;
buf_nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
buf_nonce = ucmalloc(LNONCE);
buf_cipher = ucmalloc(ciphersize);
buf_clear = ucmalloc(ciphersize);
out_size = 0;
@@ -530,7 +610,7 @@ size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *
byte *signature = NULL;
byte *signature_cr = NULL;
size_t siglen = crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
size_t siglen_cr = siglen + PCP_CRYPTO_ADD + crypto_secretbox_NONCEBYTES;
size_t siglen_cr = siglen + LMAC + LNONCE;
crypto_generichash_state *st = NULL;
byte *hash = NULL;
@@ -539,26 +619,27 @@ size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *
hash = ucmalloc(crypto_generichash_BYTES_MAX);
crypto_generichash_init(st, NULL, 0, 0);
signature_cr = ucmalloc(siglen_cr);
signature = ucmalloc(siglen);
}
in_buf = ucmalloc(PCP_BLOCK_SIZE_IN);
while(!ps_end(in)) {
cur_bufsize = ps_read(in, in_buf, PCP_BLOCK_SIZE_IN);
if(cur_bufsize <= PCP_CRYPTO_ADD)
if(cur_bufsize <= LMAC)
break; /* no valid cipher block */
if(recverify != NULL) {
if(cur_bufsize < PCP_BLOCK_SIZE_IN || ps_end(in)) {
/* pull out signature */
memcpy(signature_cr, &in_buf[cur_bufsize - siglen_cr], siglen_cr);
cur_bufsize -= siglen_cr;
/* pull out signature */
memcpy(signature_cr, &in_buf[cur_bufsize - siglen_cr], siglen_cr);
cur_bufsize -= siglen_cr;
}
}
ciphersize = cur_bufsize - crypto_secretbox_NONCEBYTES;
memcpy(buf_nonce, in_buf, crypto_secretbox_NONCEBYTES);
memcpy(buf_cipher, &in_buf[crypto_secretbox_NONCEBYTES], ciphersize);
ciphersize = cur_bufsize - LNONCE;
memcpy(buf_nonce, in_buf, LNONCE);
memcpy(buf_cipher, &in_buf[LNONCE], ciphersize);
/* extract counter from nonce and check if it is in line with previous one
TODO: save unordered buffers to disk and continue writing to out if
@@ -566,25 +647,25 @@ size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *
ctr = _get_nonce_ctr(buf_nonce);
if(ctr -1 != pastctr) {
fatal(ptx, "Mangled packet order, bailing out (got: %ld, expected: %ld)!\n",
ctr, pastctr+1);
ctr, pastctr+1);
out_size = 0;
break;
}
pastctr = ctr;
es = pcp_sodium_verify_mac(&buf_clear, buf_cipher, ciphersize, buf_nonce, symkey);
out_size += ciphersize - PCP_CRYPTO_ADD;
out_size += ciphersize - LMAC;
if(es == 0) {
ps_write(out, buf_clear, ciphersize - PCP_CRYPTO_ADD);
ps_write(out, buf_clear, ciphersize - LMAC);
if(recverify != NULL)
crypto_generichash_update(st, buf_cipher, ciphersize);
crypto_generichash_update(st, buf_cipher, ciphersize);
if(ps_err(out) != 0) {
fatal(ptx, "Failed to write decrypted output!\n");
out_size = 0;
break;
fatal(ptx, "Failed to write decrypted output!\n");
out_size = 0;
break;
}
}
else {
@@ -596,30 +677,50 @@ size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *
ucfree(in_buf, PCP_BLOCK_SIZE_IN);
ucfree(buf_cipher, ciphersize);
ucfree(buf_clear, ciphersize - PCP_CRYPTO_ADD);
ucfree(buf_clear, ciphersize - LMAC);
if(recverify != NULL) {
/* decrypt the signature */
memcpy(buf_nonce, signature_cr, crypto_secretbox_NONCEBYTES);
memcpy(buf_nonce, signature_cr, LNONCE);
es = pcp_sodium_verify_mac(&signature, &signature_cr[crypto_secretbox_NONCEBYTES],
siglen_cr - crypto_secretbox_NONCEBYTES, buf_nonce, symkey);
es = pcp_sodium_verify_mac(&signature, &signature_cr[LNONCE],
siglen_cr - LNONCE, buf_nonce, symkey);
if(es == 0) {
/* add encrypted recipient list to the hash */
crypto_generichash_update(st, recverify->cipher, recverify->ciphersize);
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
byte *verifiedhash = NULL;
verifiedhash = pcp_ed_verify(ptx, signature, siglen, recverify->pub);
if(verifiedhash == NULL)
out_size = 0;
if(recverify->pub == NULL) {
/* anonymous encrypted but with known pub signed,
dig through our list of known public keys for a match */
pcp_pubkey_t *cur;
pcphash_iteratepub(ptx, cur) {
verifiedhash = pcp_ed_verify(ptx, signature, siglen, cur);
if(verifiedhash != NULL)
break;
}
}
else {
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
/* sig verified, but the hash doesn't match */
fatal(ptx, "signed hash doesn't match actual hash of signed decrypted file content\n");
out_size = 0;
}
free(verifiedhash);
verifiedhash = pcp_ed_verify(ptx, signature, siglen, recverify->pub);
}
if(verifiedhash == NULL)
out_size = 0;
else {
if(cst_time_memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
/* sig verified, but the hash doesn't match */
fatal(ptx, "signed hash doesn't match actual hash of signed decrypted file content\n");
out_size = 0;
}
free(verifiedhash);
}
if(ptx->verbose) {
_dump("crypto.c: <= sig", signature, siglen);
_dump("crypto.c: <= nonce", buf_nonce, LNONCE);
_dump("crypto.c: <= enc sig", &signature_cr[LNONCE], siglen_cr - LNONCE);
}
}
else {
@@ -643,7 +744,6 @@ pcp_rec_t *pcp_rec_new(byte *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_
r->cipher = ucmalloc(clen);
memcpy(r->cipher, cipher, clen);
r->ciphersize = clen;
if(secret != NULL) {
r->secret = ucmalloc(sizeof(pcp_key_t));
memcpy(r->secret, secret, sizeof(pcp_key_t));
@@ -690,30 +790,25 @@ void pcp_rec_free(pcp_rec_t *r) {
uint64_t _get_nonce_ctr(byte *nonce) {
uint64_t ctr = 0;
uint8_t i = nonce[0];
uint16_t m16 = 0;
uint32_t m32 = 0;
if(i > 16) {
/* counter bigger than max allowed by protocol, could lead to overflow, therefore die hard here */
fprintf(stderr, "invalid counter size %d!", i);
abort();
}
switch(i) {
case 1:
ctr = nonce[1];
break;
case 2:
memcpy(&m16, &nonce[1], 2);
ctr = be16toh(m16);
ctr = _wireto16(&nonce[1]);
break;
case 4:
memcpy(&m32, &nonce[1], 4);
ctr = be32toh(m32);
ctr = _wireto32(&nonce[1]);
break;
case 8:
memcpy(&ctr, &nonce[1], 8);
ctr = be64toh(ctr);
ctr = _wireto64(&nonce[1]);
break;
}
@@ -777,25 +872,21 @@ byte *_gen_ctr_nonce(uint64_t ctr) {
uint8_t m8 = -1;
uint16_t m16 = -1;
uint32_t m32 = -1;
uint64_t m64 = -1;
uint8_t i = 1;
byte *nonce = pcp_gennonce();
if(ctr > m32) {
i = 8;
m64 = htobe64(ctr);
memcpy(&nonce[1], &m64, 8);
_64towire(ctr, &nonce[1]);
}
else if(ctr < m32 && ctr > m16) {
else if(ctr <= m32 && ctr > m16) {
i = 4;
m32 = htobe32(ctr);
memcpy(&nonce[1], &m32, 4);
_32towire(ctr, &nonce[1]);
}
else if(ctr < m16 && ctr > m8) {
else if(ctr <= m16 && ctr > m8) {
i = 2;
m16 = htobe16(ctr);
memcpy(&nonce[1], &m16, 2);
_16towire(ctr, &nonce[1]);
}
else {
i = 1;

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -212,11 +212,11 @@ pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p
cur_bufsize = offset;
gotsig = 1;
if(z85) {
cur_bufsize -= 1;
memcpy(z85encoded, &in_full[offset], zlen);
cur_bufsize -= 1;
memcpy(z85encoded, &in_full[offset], zlen);
}
else
memcpy(sighash, &in_full[offset + strlen(binsigstart)], mlen);
memcpy(sighash, &in_full[offset + strlen(binsigstart)], mlen);
}
else if(full_bufsize - offset == siglen) {
/* sig fits within the 2nd half */
@@ -225,11 +225,11 @@ pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p
next_bufsize -= siglen;
gotsig = 1;
if(z85) {
cur_bufsize -= 1;
memcpy(z85encoded, &in_full[full_bufsize - siglen], siglen);
cur_bufsize -= 1;
memcpy(z85encoded, &in_full[full_bufsize - siglen], siglen);
}
else
memcpy(sighash, &in_full[full_bufsize - mlen], mlen);
memcpy(sighash, &in_full[full_bufsize - mlen], mlen);
}
else
offset = 0;
@@ -276,7 +276,7 @@ pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p
pcphash_iteratepub(ptx, p) {
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
if(verifiedhash != NULL)
break;
break;
}
/* no pubkey found yet, try our own */
@@ -284,13 +284,13 @@ pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p
pcp_pubkey_t *pub;
pcphash_iterate(ptx, k) {
if(k->type == PCP_KEY_TYPE_MAINSECRET) {
pub = pcpkey_pub_from_secret(k);
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, pub);
if(verifiedhash != NULL) {
/* good, self-signed */
p = pub;
break;
}
pub = pcpkey_pub_from_secret(k);
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, pub);
if(verifiedhash != NULL) {
/* good, self-signed */
p = pub;
break;
}
}
}
}
@@ -301,7 +301,7 @@ pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p
if(verifiedhash == NULL)
goto errvb1;
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
if(cst_time_memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
/* sig verified, but the hash doesn't */
fatal(ptx, "signed hash doesn't match actual hash of signed file content\n");
free(verifiedhash);
@@ -341,7 +341,7 @@ size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s) {
size_t mlen = + crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
ps_print(out, "%s\r\nVersion: PCP v%d.%d.%d\r\n",
PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
size_t zlen;
char *z85encoded = pcp_z85_encode((byte*)signature, mlen, &zlen, 1);
ps_print(out, "%s\r\n%s\r\n", z85encoded, PCP_SIG_END);
@@ -416,7 +416,7 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream
pcphash_iteratepub(ptx, p) {
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
if(verifiedhash != NULL)
break;
break;
}
/* no pubkey found yet, try our own */
@@ -424,13 +424,13 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream
pcp_pubkey_t *pub;
pcphash_iterate(ptx, k) {
if(k->type == PCP_KEY_TYPE_MAINSECRET) {
pub = pcpkey_pub_from_secret(k);
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, pub);
if(verifiedhash != NULL) {
/* good, self-signed */
p = pub;
break;
}
pub = pcpkey_pub_from_secret(k);
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, pub);
if(verifiedhash != NULL) {
/* good, self-signed */
p = pub;
break;
}
}
}
}
@@ -441,7 +441,7 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream
if(verifiedhash == NULL)
goto errdea4;
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
if(cst_time_memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
/* sig verified, but the hash doesn't */
fatal(ptx, "signed hash doesn't match actual hash of signed file content\n");
goto errdea5;

View File

@@ -8,6 +8,7 @@ PCPEXPORT = pcp.h \
pcp/keyhash.h \
pcp/mem.h \
pcp/platform.h \
pcp/plist.h \
pcp/randomart.h \
pcp/uthash.h \
pcp/vault.h \
@@ -22,7 +23,7 @@ PCPEXPORT = pcp.h \
pcp/context.h \
pcp/structs.h \
pcp/util.h \
pcp/plist.h \
pcp/readpass.h \
pcp/scrypt.h
nobase_include_HEADERS = $(PCPEXPORT)

View File

@@ -22,6 +22,7 @@ extern "C" {
#include "pcp/platform.h"
#include "pcp/plist.h"
#include "pcp/randomart.h"
#include "pcp/readpass.h"
#include "pcp/scrypt.h"
#include "pcp/structs.h"
#include "pcp/uthash.h"

View File

@@ -9,15 +9,9 @@
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define if be32toh() is available */
#undef HAVE_BE32TOH
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <endian.h> header file. */
#undef HAVE_ENDIAN_H
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
@@ -51,9 +45,6 @@
/* Define to 1 if you have the `getopt_long' function. */
#undef HAVE_GETOPT_LONG
/* Define if htobe32() is available */
#undef HAVE_HTOBE32
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@@ -126,9 +117,6 @@
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if you have the <sys/endian.h> header file. */
#undef HAVE_SYS_ENDIAN_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2015 T.Linden.
Copyright (C) 2013-2016 T.Linden.
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
@@ -141,7 +141,7 @@
*/
byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
byte *message, size_t messagesize,
size_t *csize);
size_t *csize);
/** Asymmetrically decrypt a message.
@@ -167,7 +167,7 @@ byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
*/
byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
byte *cipher, size_t ciphersize,
size_t *dsize);
size_t *dsize);
/** Asymmetrically encrypt a file or a buffer stream.
@@ -183,7 +183,9 @@ byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
\param[out] out Stream to write encrypted result to.
\param[in] s Secret key structure of the sender.
\param[in] s Secret key structure of the sender for encryption.
\param[in] s Secret key structure of the sender for signing.
\param[in] p Public key hash containing a list of the recipients.
@@ -193,7 +195,8 @@ byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
\return Returns the size of the output written to the output stream or 0 in case of errors.
*/
size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubkey_t *p, int signcrypt, int anon);
size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s,
pcp_key_t *ss, pcp_pubkey_t *p, int signcrypt, int anon);
/** Symmetrically encrypt a file or a buffer stream.

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -57,6 +57,8 @@ typedef unsigned char byte; /* Single unsigned byte = 8 bits */
typedef unsigned short dbyte; /* Double byte = 16 bits */
typedef unsigned int qbyte; /* Quad byte = 32 bits */
/* key stuff, deprecated. */
#define PCP_ENFILE_HEADER "----- BEGIN PCP ENCRYPTED FILE -----\r\n"
#define PCP_ENFILE_FOOTER "\r\n----- END PCP ENCRYPTED FILE -----\r\n"
@@ -102,8 +104,18 @@ typedef enum _PCP_KEY_TYPES {
/** @}
*/
/* save typing, dammit */
#define PCP_ENCRYPT_MAC crypto_secretbox_ZEROBYTES + crypto_secretbox_NONCEBYTES
/* shortcuts for key lengths and stuff to save typing */
#define LEDPUB crypto_sign_PUBLICKEYBYTES
#define LEDSEC crypto_sign_SECRETKEYBYTES
#define LBOXPUB crypto_box_PUBLICKEYBYTES
#define LBOXSEC crypto_box_SECRETKEYBYTES
#define LNONCE crypto_secretbox_NONCEBYTES
#define LMAC crypto_secretbox_MACBYTES
#define LSEC LBOXSEC + LEDSEC + LEDSEC + crypto_secretbox_MACBYTES
#define LSHA 32 /* sha256 hash length */
#define LHASH crypto_generichash_BYTES_MAX
#define LSIG crypto_sign_BYTES
/* vault id */
#define PCP_VAULT_ID 14
@@ -115,13 +127,14 @@ typedef enum _PCP_KEY_TYPES {
/* crypto file format stuff */
#define PCP_ASYM_CIPHER 5
#define PCP_ASYM_CIPHER_ANON 6
#define PCP_ASYM_CIPHER_ANON_SIG 7
#define PCP_SYM_CIPHER 23
#define PCP_ASYM_CIPHER_SIG 24
#define PCP_BLOCK_SIZE 32 * 1024
#define PCP_CRYPTO_ADD (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
#define PCP_BLOCK_SIZE_IN (PCP_BLOCK_SIZE) + PCP_CRYPTO_ADD + crypto_secretbox_NONCEBYTES
#define PCP_ASYM_RECIPIENT_SIZE crypto_secretbox_KEYBYTES + PCP_CRYPTO_ADD + crypto_secretbox_NONCEBYTES
//#define PCP_CRYPTO_ADD (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
#define PCP_BLOCK_SIZE_IN (PCP_BLOCK_SIZE) + crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES
#define PCP_ASYM_RECIPIENT_SIZE crypto_secretbox_KEYBYTES + crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES
/* #define PCP_ASYM_ADD_SENDER_PUB */

View File

@@ -28,6 +28,10 @@
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#include "defines.h"
#include "platform.h"
#include "mem.h"
@@ -267,6 +271,10 @@ void pcp_seckeyblob(Buffer *b, pcp_key_t *k);
void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k);
Buffer *pcp_keyblob(void *k, int type); /* allocates blob */
/* reads key from blob */
pcp_key_t *pcp_blob2key(Buffer *b); /* allocates key */
pcp_pubkey_t *pcp_blob2pubkey(Buffer *b);
/** Make a sanity check of the given public key structure.
\param[in] ptx pcp context.
@@ -309,6 +317,8 @@ void pcp_dumppubkey(pcp_pubkey_t *k);
*/
void pcpkey_setowner(pcp_key_t *key, char *owner, char *mail);
double pcp_getentropy(char *source);
#endif /* _HAVE_PCP_KEYPAIR_H */
/**@}*/

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2015 T.Linden.
Copyright (C) 2013-2016 T.Linden.
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
@@ -54,7 +54,7 @@
Also, don't free() the keyhash or the temporary key pointer
yourself. Use pcphash_clean() instead when done.
*/
#define pcphash_iterate(ptx, key) \
#define pcphash_iterate(ptx, key) \
pcp_key_t *__k = NULL; \
HASH_ITER(hh, ptx->pcpkey_hash, key, __k)
@@ -73,7 +73,7 @@
Also, don't free() the keyhash or the temporary key pointer
yourself. Use pcphash_clean() instead when done.
*/
#define pcphash_iteratepub(ptx, key) \
#define pcphash_iteratepub(ptx, key) \
pcp_pubkey_t *__p = NULL; \
HASH_ITER(hh, ptx->pcppubkey_hash, key, __p)
@@ -142,7 +142,7 @@ int pcphash_countpub(PCPCTX *ptx);
#define pcphash_iteratekeysig(ptx, key) \
#define pcphash_iteratekeysig(ptx, key) \
pcp_keysig_t *__s = NULL; \
HASH_ITER(hh, ptx->pcpkeysig_hash, key, __s)

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -35,16 +35,14 @@
#define PCP_RAW_KEYSIGSIZE sizeof(pcp_keysig_t) - sizeof(UT_hash_handle)
pcp_keysig_t *keysig2be(pcp_keysig_t *s);
pcp_keysig_t *keysig2native(pcp_keysig_t *s);
/* put a keysig into a buffer, convert to big endian while at it */
Buffer *pcp_keysig2blob(pcp_keysig_t *s);
void pcp_keysig2blob(Buffer *b, pcp_keysig_t *s);
/* same, but allocs buffer */
Buffer *pcp_keysigblob(pcp_keysig_t *s);
/* fetch a keysig from a buffer, usually loaded from vault */
pcp_keysig_t *pcp_keysig_new(Buffer *blob);
pcp_keysig_t *pcp_blob2keysig(Buffer *blob);
/* debug print a keysig */
void pcp_dumpkeysig(pcp_keysig_t *s);

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2014 T.v.Dein.
Copyright (C) 2014-2016 T.v.Dein.
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
@@ -27,44 +27,49 @@
#define _HAVE_PCP_MGMT_H
#if defined __linux__ || defined __GNU__ || defined __GLIBC__
# ifndef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE 1
# endif
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE 1
#endif
#
# ifndef _XOPEN_SOURCE
# define _XOPEN_SOURCE 1
# endif
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 1
#endif
#
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#
#ifndef __USE_XOPEN
#define __USE_XOPEN 1
#endif
#
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
#else
# define _BSD_SOURCE 1
#define _BSD_SOURCE 1
#endif
#include <sodium.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_JSON
// #ifdef HAVE_JSON
#ifndef JANSSON_H
#include <jansson.h>
#endif
#include "buffer.h"
#include "context.h"
#include "defines.h"
#include "platform.h"
#include "structs.h"
#include "mem.h"
#include "ed.h"
#include "key.h"
#include "keysig.h"
#include "buffer.h"
#include "mem.h"
#include "platform.h"
#include "scrypt.h"
#include "context.h"
#include "structs.h"
/* key management api, export, import, and stuff */
/**
* \defgroup PubKeyExport KEYEXPORT
* @{
@@ -72,10 +77,6 @@
Functions to export and import keys in various formats.
*/
/** RFC4880 alike public key export with some modifications.
(Refer to the INTERNALS section of the pcp(1) manual page for details.
@@ -85,11 +86,9 @@
\return the function returns a Buffer object containing the binary
blob in the format described above.
*/
Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk);
Buffer *pcp_export_rfc_pub(PCPCTX *ptx, pcp_key_t *sk);
/** Export a public key in PBP format.
Export a public key in the format described at
@@ -105,7 +104,8 @@ Buffer *pcp_export_pbp_pub(pcp_key_t *sk);
/** Export secret key.
Export a secret key. (refer to the INTERNALS section of the pcp(1) manual page for details).
Export a secret key. (refer to the INTERNALS section of the pcp(1) manual
page for details).
\param[in] ptx context.
@@ -130,7 +130,8 @@ Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase);
\return the function returns a Buffer object containing the binary
blob containing a JSON string.
*/
Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig, size_t siglen);
Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig,
size_t siglen);
/** Export secret key in JSON format
@@ -143,7 +144,8 @@ Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig, size_t siglen
\return the function returns a Buffer object containing the binary
blob containing a JSON string.
*/
Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce, byte *cipher, size_t clen);
Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce,
byte *cipher, size_t clen);
/** Convert secret key struct into JSON struct
@@ -152,7 +154,7 @@ Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce, byte *ci
\return returns a json_t structure (see libjansson docs for details)
*/
json_t *pcp_sk2json(pcp_key_t *sk, byte *sig,size_t siglen);
json_t *pcp_sk2json(pcp_key_t *sk, byte *sig, size_t siglen);
/** Convert public key struct into JSON struct
@@ -174,14 +176,19 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob);
pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob);
/* import secret key */
pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase);
pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase);
pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphrase);
pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize,
char *passphrase);
pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize,
char *passphrase);
pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher,
char *passphrase);
/* helpers */
int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h);
int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk);
int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader);
int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p,
pcp_keysig_t *sk);
int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p,
rfc_pub_sig_s *subheader);
#endif // _HAVE_PCP_MGMT_H

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -25,47 +25,6 @@
#include "config.h"
#ifdef HAVE_ENDIAN_H
# include <endian.h>
#else /* no endian.h */
# ifdef HAVE_SYS_ENDIAN_H
# include <sys/types.h>
# include <sys/endian.h>
# ifndef HAVE_BE32TOH
# /* openbsd, use aliases */
# define be16toh betoh16
# define be32toh betoh32
# define be64toh betoh64
# endif
# else /* no sys/endian.h */
# ifdef __CPU_IS_BIG_ENDIAN
# define be16toh(x) (x)
# define htobe16(x) (x)
# define be32toh(x) (x)
# define htobe32(x) (x)
# define be64toh(x) (x)
# define htobe64(x) (x)
# else
# ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
# else
# ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
# else
# error Need either netinet/in.h or arpa/inet.h for ntohl() and htonl()
# endif
# endif
# define be16toh(x) ((uint16_t)ntohl((uint16_t)(x)))
# define htobe16(x) ((uint16_t)htonl((uint16_t)(x)))
# define be32toh(x) ((uint32_t)ntohl((uint32_t)(x)))
# define htobe32(x) ((uint32_t)htonl((uint32_t)(x)))
# define be64toh(x) ((uint64_t)ntohl((uint64_t)(x)))
# define htobe64(x) ((uint64_t)htonl((uint64_t)(x)))
# endif
# endif /* HAVE_SYS_ENDIAN_H */
#endif /* HAVE_ENDIAN_H */
#ifndef HAVE_ARC4RANDOM
#include <sodium.h>
#define arc4random() randombytes_random()

View File

@@ -35,9 +35,14 @@
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/wait.h>
#include "defines.h"
#include "context.h"
#include "pcp.h"
#include "util.h"
#define MAXPASSLEN 2048
@@ -52,6 +57,13 @@
* ${passwd}. The obscure name is to avoid namespace collisions due to the
* getpass / readpass / readpassphrase / etc. functions in various libraries.
*/
int pcp_readpass(char **, const char *, const char *, int, char *);
int pcp_readpass(PCPCTX *ptx, char **passwd, const char *prompt,
const char *confirmprompt, int devtty, char *readfromfile);
/**
from encfs getUserKey().
*/
int pcp_readpass_fromprog(PCPCTX *ptx, char **passwd, const char *askpass);
#endif /* !_READPASS_H_ */

View File

@@ -70,21 +70,21 @@
*/
struct _pcp_key_t {
byte masterpub[32]; /**< ED25519 master public key signing key */
byte mastersecret[64]; /**< ED25519 master secret key signing key */
byte pub[32]; /**< Curve25519 encryption public key */
byte secret[32]; /**< Curve25519 encryption secret key */
byte edpub[32]; /**< ED25519 public signing key */
byte edsecret[64]; /**< ED25519 secret signing key */
byte nonce[24]; /**< random nonce used to encrypt secret keys */
byte encrypted[176]; /**< concatenated and encrypted secret keys */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
byte masterpub[LEDPUB]; /**< ED25519 master public key signing key */
byte mastersecret[LEDSEC]; /**< ED25519 master secret key signing key */
byte pub[LBOXPUB]; /**< Curve25519 encryption public key */
byte secret[LBOXSEC]; /**< Curve25519 encryption secret key */
byte edpub[LEDPUB]; /**< ED25519 public signing key */
byte edsecret[LEDSEC]; /**< ED25519 secret signing key */
byte nonce[LNONCE]; /**< random nonce used to encrypt secret keys */
byte encrypted[LSEC]; /**< concatenated and encrypted secret keys */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
UT_hash_handle hh;
};
@@ -99,18 +99,17 @@ typedef struct _pcp_key_t pcp_key_t;
without the secret and nonce fields.
*/
struct _pcp_pubkey_t {
byte masterpub[32]; /**< ED25519 master public key signing key */
byte sigpub[32]; /**< ED25519 public signing key */
byte pub[32]; /**< Curve25519 encryption public key */
byte edpub[32]; /**< ED25519 public signing key (FIXME: huh? 2 of them???) */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
uint8_t valid; /**< 1 if import signature verified, 0 if not */
byte masterpub[LEDPUB]; /**< ED25519 master public key signing key */
byte pub[LBOXPUB]; /**< Curve25519 encryption public key */
byte edpub[LEDPUB]; /**< ED25519 public signing key (FIXME: huh? 2 of them???) */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
uint8_t valid; /**< 1 if import signature verified, 0 if not */
byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES]; /**< raw binary blob of pubkey export signature */
UT_hash_handle hh;
};
@@ -122,7 +121,7 @@ typedef struct _pcp_pubkey_t pcp_pubkey_t;
/* the PBP public key format */
/* keys.mp+keys.cp+keys.sp+keys.name */
struct _pbp_pubkey_t {
byte sigpub[crypto_sign_PUBLICKEYBYTES];
byte masterpub[crypto_sign_PUBLICKEYBYTES];
byte edpub[crypto_sign_PUBLICKEYBYTES];
byte pub[crypto_box_PUBLICKEYBYTES];
char iso_ctime[32];
@@ -158,7 +157,7 @@ struct _pcp_keysig_t {
uint8_t type;
uint32_t size;
char id[17];
byte checksum[32];
byte checksum[LSHA];
byte *blob;
UT_hash_handle hh;
};
@@ -229,7 +228,7 @@ struct _vault_t {
time_t modified; /**< mtime */
mode_t mode; /**< File mode */
uint32_t version; /**< Vault version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
byte checksum[LSHA]; /**< SHA256 checksum over the whole vault */
};
/** Name of the struct */
@@ -240,7 +239,7 @@ typedef struct _vault_t vault_t;
struct _vault_header_t {
uint8_t fileid; /**< File id, proprietary. Marks the vault as a vault */
uint32_t version; /**< File version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
byte checksum[LSHA]; /**< SHA256 checksum over the whole vault */
};
/** Name of the struct */
@@ -252,7 +251,7 @@ struct _vault_item_header_t {
uint8_t type; /**< Item type (secret key, public, key, keysig, \see _PCP_KEY_TYPES */
uint32_t size; /**< Size of the item */
uint32_t version; /**< Version of the item */
byte checksum[32]; /**< SHA256 checksum of the item */
byte checksum[LSHA]; /**< SHA256 checksum of the item */
};
/** Name of the struct */
@@ -312,6 +311,7 @@ struct _pcp_stream_t {
Buffer *cache; /**< The caching Buffer object (for look ahead read) */
Buffer *next; /**< The caching Next-Buffer object (for look ahead read) */
Buffer *save; /**< Temporary buffer to backup overflow data */
byte *xb; /**< Temporary byte buffer for reading/writing data */
uint8_t is_buffer; /**< Set to 1 if the backend is a Buffer */
uint8_t eof; /**< Set to 1 if EOF reached */
uint8_t err; /**< Set to 1 if an error occured */

View File

@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include "platform.h"
#include "defines.h"
@@ -115,6 +116,27 @@ char *_bin2hex(byte *bin, size_t len);
*/
size_t _hex2bin(const char *hex_str, unsigned char *byte_array, size_t byte_array_max);
/** compare two memory regions in a constant time
\param[in] m1 array1
\param[in] m2 array2
\param[in] n size in bytes to compare
\return 0 if m1 and m2 are equal up to n
*/
int cst_time_memcmp(const void *m1, const void *m2, size_t n);
// be32toh
uint64_t _wireto64(byte *data);
uint32_t _wireto32(byte *data);
uint16_t _wireto16(byte *data);
// htobe32
void _64towire(uint64_t i, byte *data);
void _32towire(uint32_t i, byte *data);
void _16towire(uint16_t i, byte *data);
#endif /* _HAVE_PCP_UTIL_H */
/**@}*/

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2017 T.v.Dein.
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
@@ -24,8 +24,8 @@
#define _HAVE_PCP_VERSION
#define PCP_VERSION_MAJOR 0
#define PCP_VERSION_MINOR 3
#define PCP_VERSION_PATCH 0
#define PCP_VERSION_MINOR 4
#define PCP_VERSION_PATCH 1
#define PCP_VERSION PCP_MAKE_VERSION(PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH)
#define PCP_MAKE_VERSION(major, minor, patch) ((major * 10000) + (minor * 100) + (patch))

View File

@@ -20,12 +20,15 @@
#ifndef __ZMQ_Z85_H_INCLUDED__
#define __ZMQ_Z85_H_INCLUDED__
#define __STDC_LIMIT_MACROS
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
uint8_t *zmq_z85_decode (uint8_t *dest, char *string);
char *zmq_z85_encode (char *dest, uint8_t *data, size_t size);
uint8_t *zmq_z85_decode (uint8_t *dest, const char *string);
char *zmq_z85_encode (char *dest, const uint8_t *data, size_t size);
#endif

View File

@@ -9,14 +9,14 @@ unsigned jen_hash ( unsigned char *k, unsigned length, unsigned initval ) {
while ( len >= 12 ) {
a += ( k[0] + ( (unsigned)k[1] << 8 )
+ ( (unsigned)k[2] << 16 )
+ ( (unsigned)k[3] << 24 ) );
+ ( (unsigned)k[2] << 16 )
+ ( (unsigned)k[3] << 24 ) );
b += ( k[4] + ( (unsigned)k[5] << 8 )
+ ( (unsigned)k[6] << 16 )
+ ( (unsigned)k[7] << 24 ) );
+ ( (unsigned)k[6] << 16 )
+ ( (unsigned)k[7] << 24 ) );
c += ( k[8] + ( (unsigned)k[9] << 8 )
+ ( (unsigned)k[10] << 16 )
+ ( (unsigned)k[11] << 24 ) );
+ ( (unsigned)k[10] << 16 )
+ ( (unsigned)k[11] << 24 ) );
jen_mix ( a, b, c );

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -19,7 +19,6 @@
You can contact me by mail: <tom AT vondein DOT org>.
*/
#include "key.h"
#include "context.h"
@@ -33,13 +32,13 @@ byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce) {
size_t plen = strnlen(passphrase, 255);
/* create the scrypt hash */
byte *scrypted = pcp_scrypt(ptx, passphrase, plen, nonce, crypto_secretbox_NONCEBYTES);
byte *scrypted = pcp_scrypt(ptx, passphrase, plen, nonce, LNONCE);
/* make a hash from the scrypt() result */
crypto_hash_sha256(key, (byte*)scrypted, 64);
crypto_hash_sha256(key, (byte *)scrypted, 64);
/* turn the 32byte hash into a secret key */
key[0] &= 248;
key[0] &= 248;
key[31] &= 127;
key[31] |= 64;
@@ -48,11 +47,10 @@ byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce) {
return key;
}
char *pcp_getkeyid(pcp_key_t *k) {
uint32_t s, p;
p = jen_hash(k->pub, 32, JEN_PSALT);
s = jen_hash(k->edpub, 32, JEN_SSALT);
p = jen_hash(k->pub, LBOXPUB, JEN_PSALT);
s = jen_hash(k->edpub, LEDPUB, JEN_SSALT);
char *id = ucmalloc(17);
snprintf(id, 17, "%08X%08X", p, s);
return id;
@@ -61,14 +59,15 @@ char *pcp_getkeyid(pcp_key_t *k) {
/* same as above but for imported pbp keys */
char *pcp_getpubkeyid(pcp_pubkey_t *k) {
uint32_t s, p;
p = jen_hash(k->pub, 32, JEN_PSALT);
s = jen_hash(k->edpub, 32, JEN_SSALT);
p = jen_hash(k->pub, LBOXPUB, JEN_PSALT);
s = jen_hash(k->edpub, LEDPUB, JEN_SSALT);
char *id = ucmalloc(17);
snprintf(id, 17, "%08X%08X", p, s);
return id;
}
void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *epk) {
void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk,
byte *epk) {
/* generate keypairs from random seed */
byte *ms = urmalloc(32);
byte *ss = urmalloc(32);
@@ -82,7 +81,7 @@ void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *e
/* curve25519 secret key */
memcpy(csk, cs, 32);
csk[0] &= 248;
csk[0] &= 248;
csk[31] &= 63;
csk[31] |= 64;
@@ -94,53 +93,53 @@ void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *e
ucfree(cs, 32);
}
pcp_key_t * pcpkey_new () {
byte *mp = ucmalloc(32);
byte *ms = ucmalloc(64);
byte *sp = ucmalloc(32);
byte *ss = ucmalloc(64);
byte *cp = ucmalloc(32);
byte *cs = ucmalloc(32);
pcp_key_t *pcpkey_new() {
byte *mp = ucmalloc(LEDPUB);
byte *ms = ucmalloc(LEDSEC);
byte *sp = ucmalloc(LEDPUB);
byte *ss = ucmalloc(LEDSEC);
byte *cp = ucmalloc(LBOXPUB);
byte *cs = ucmalloc(LBOXSEC);
/* generate key material */
pcp_keypairs(ms, mp, cs, cp, ss, sp);
/* fill in our struct */
pcp_key_t *key = urmalloc(sizeof(pcp_key_t));
memcpy (key->masterpub, mp, 32);
memcpy (key->mastersecret, ms, 64);
memcpy (key->pub, cp, 32);
memcpy (key->secret, cs, 32);
memcpy (key->edpub, sp, 32);
memcpy (key->edsecret, ss, 64);
memcpy(key->masterpub, mp, LEDPUB);
memcpy(key->mastersecret, ms, LEDSEC);
memcpy(key->pub, cp, LBOXPUB);
memcpy(key->secret, cs, LBOXSEC);
memcpy(key->edpub, sp, LEDPUB);
memcpy(key->edsecret, ss, LEDSEC);
char *id = pcp_getkeyid(key);
memcpy (key->id, id, 17);
memcpy(key->id, id, 17);
free(id);
key->ctime = (long)time(0);
key->version = PCP_KEY_VERSION;
key->serial = arc4random();
key->type = PCP_KEY_TYPE_SECRET;
key->serial = arc4random();
key->type = PCP_KEY_TYPE_SECRET;
key->owner[0] = '\0';
key->mail[0] = '\0';
/* clean up */
ucfree(ms, 64);
ucfree(ss, 64);
ucfree(mp, 32);
ucfree(sp, 32);
ucfree(cs, 32);
ucfree(cp, 32);
ucfree(ms, LEDSEC);
ucfree(ss, LEDSEC);
ucfree(mp, LEDPUB);
ucfree(sp, LEDPUB);
ucfree(cs, LBOXSEC);
ucfree(cp, LBOXPUB);
return key;
}
byte * pcp_gennonce() {
byte *nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
arc4random_buf(nonce, crypto_secretbox_NONCEBYTES);
byte *pcp_gennonce() {
byte *nonce = ucmalloc(LNONCE);
arc4random_buf(nonce, LNONCE);
return nonce;
}
@@ -150,39 +149,36 @@ void pcpkey_setowner(pcp_key_t *key, char *owner, char *mail) {
}
pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
if(key->nonce[0] == 0) {
if (key->nonce[0] == 0) {
byte *nonce = pcp_gennonce();
memcpy (key->nonce, nonce, crypto_secretbox_NONCEBYTES);
ucfree(nonce, crypto_secretbox_NONCEBYTES);
memcpy(key->nonce, nonce, LNONCE);
ucfree(nonce, LNONCE);
}
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
byte *encrypted;
size_t es;
Buffer *both = buffer_new(128, "keypack");
buffer_add(both, key->mastersecret, 64);
buffer_add(both, key->edsecret, 64);
buffer_add(both, key->secret, 32);
buffer_add(both, key->mastersecret, LEDSEC);
buffer_add(both, key->edsecret, LEDSEC);
buffer_add(both, key->secret, LBOXSEC);
es = pcp_sodium_mac(&encrypted, buffer_get(both), buffer_size(both), key->nonce, encryptkey);
es = pcp_sodium_mac(&encrypted, buffer_get(both), buffer_size(both),
key->nonce, encryptkey);
buffer_free(both);
sfree(encryptkey);
if(es == 176) { /* FIXME: calc! */
if (es == LSEC) {
/* success */
memcpy(key->encrypted, encrypted, 176);
memcpy(key->encrypted, encrypted, LSEC);
ucfree(encrypted, es);
arc4random_buf(key->secret, 32);
arc4random_buf(key->edsecret, 64);
arc4random_buf(key->mastersecret, 64);
key->secret[0] = 0;
key->edsecret[0] = 0;
key->mastersecret[0] = 0;
}
else {
memset(key->secret, 0, LBOXSEC);
memset(key->edsecret, 0, LEDSEC);
memset(key->mastersecret, 0, LEDSEC);
} else {
fatal(ptx, "failed to encrypt the secret key!\n");
ucfree(encrypted, es);
ucfree(key, sizeof(pcp_key_t));
@@ -193,25 +189,25 @@ pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
}
pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
byte *decrypted;
byte *decrypted = ucmalloc(LSEC - crypto_secretbox_MACBYTES);
size_t es;
es = pcp_sodium_verify_mac(&decrypted, key->encrypted, 176, key->nonce, encryptkey);
es = pcp_sodium_verify_mac(&decrypted, key->encrypted, LSEC, key->nonce,
encryptkey);
sfree(encryptkey);
if(es == 0) {
if (es == 0) {
/* success */
memcpy(key->mastersecret, decrypted, 64);
memcpy(key->edsecret, decrypted + 64, 64);
memcpy(key->secret, decrypted +128, 32);
ucfree(decrypted, 160);
}
else {
memcpy(key->mastersecret, decrypted, LEDSEC);
memcpy(key->edsecret, decrypted + LEDSEC, LEDSEC);
memcpy(key->secret, decrypted + LEDSEC + LEDSEC, LBOXSEC);
ucfree(decrypted, LEDSEC + LEDSEC + LBOXSEC);
} else {
fatal(ptx, "failed to decrypt the secret key (got %d, expected 32)!\n", es);
ucfree(decrypted, 160);
ucfree(decrypted, LEDSEC + LEDSEC + LBOXSEC);
return NULL;
}
@@ -219,17 +215,17 @@ pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
}
pcp_pubkey_t *pcpkey_pub_from_secret(pcp_key_t *key) {
pcp_pubkey_t *pub = urmalloc(sizeof (pcp_pubkey_t));
memcpy(pub->masterpub, key->masterpub, 32);
memcpy(pub->pub, key->pub, 32);
memcpy(pub->edpub, key->edpub, 32);
pcp_pubkey_t *pub = urmalloc(sizeof(pcp_pubkey_t));
memcpy(pub->masterpub, key->masterpub, LEDPUB);
memcpy(pub->pub, key->pub, LBOXPUB);
memcpy(pub->edpub, key->edpub, LEDSEC);
memcpy(pub->owner, key->owner, 255);
memcpy(pub->mail, key->mail, 255);
memcpy(pub->id, key->id, 17);
pub->version = key->version;
pub->type = PCP_KEY_TYPE_PUBLIC;
pub->ctime = key->ctime;
pub->serial = key->serial;
pub->type = PCP_KEY_TYPE_PUBLIC;
pub->ctime = key->ctime;
pub->serial = key->serial;
return pub;
}
@@ -245,152 +241,137 @@ char *pcpkey_get_art(pcp_key_t *k) {
byte *pcppubkey_getchecksum(pcp_pubkey_t *k) {
byte *hash = ucmalloc(32);
crypto_hash_sha256(hash, k->pub, 32);
crypto_hash_sha256(hash, k->pub, LBOXPUB);
return hash;
}
byte *pcpkey_getchecksum(pcp_key_t *k) {
byte *hash = ucmalloc(32);
crypto_hash_sha256(hash, k->pub, 32);
crypto_hash_sha256(hash, k->pub, LBOXPUB);
return hash;
}
pcp_key_t * key2be(pcp_key_t *k) {
#ifdef __CPU_IS_BIG_ENDIAN
return k;
#else
uint32_t version = k->version;
byte* p = (byte*)&version;
if(p[0] != 0) {
k->version = htobe32(k->version);
k->serial = htobe32(k->serial);
k->ctime = htobe64(k->ctime);
}
return k;
#endif
}
pcp_key_t *key2native(pcp_key_t *k) {
#ifdef __CPU_IS_BIG_ENDIAN
return k;
#else
k->version = be32toh(k->version);
k->serial = be32toh(k->serial);
k->ctime = be64toh(k->ctime);
return k;
#endif
}
pcp_pubkey_t * pubkey2be(pcp_pubkey_t *k) {
#ifdef __CPU_IS_BIG_ENDIAN
return k;
#else
uint32_t version = k->version;
byte* p = (byte*)&version;
if(p[0] != 0) {
k->version = htobe32(k->version);
k->serial = htobe32(k->serial);
k->ctime = htobe64(k->ctime);
}
return k;
#endif
}
pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k) {
#ifdef __CPU_IS_BIG_ENDIAN
return k;
#else
k->version = be32toh(k->version);
k->serial = be32toh(k->serial);
k->ctime = be64toh(k->ctime);
return k;
#endif
}
void pcp_seckeyblob(Buffer *b, pcp_key_t *k) {
buffer_add(b, k->masterpub, 32);
buffer_add(b, k->mastersecret, 64);
buffer_add(b, k->pub, 32);
buffer_add(b, k->secret, 32);
buffer_add(b, k->edpub, 32);
buffer_add(b, k->edsecret, 64);
buffer_add(b, k->nonce, 24);
buffer_add(b, k->encrypted, 176);
buffer_add(b, k->owner, 255);
buffer_add(b, k->mail, 255);
buffer_add(b, k->id, 17);
buffer_add8(b, k->type);
buffer_add64(b, k->ctime);
buffer_add32(b, k->version);
buffer_add32(b, k->serial);
}
void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k) {
buffer_add(b, k->masterpub, 32);
buffer_add(b, k->sigpub, 32);
buffer_add(b, k->pub, 32);
buffer_add(b, k->edpub, 32);
buffer_add(b, k->masterpub, LEDPUB);
buffer_add(b, k->pub, LBOXPUB);
buffer_add(b, k->edpub, LEDPUB);
buffer_add(b, k->owner, 255);
buffer_add(b, k->mail, 255);
buffer_add(b, k->id, 17);
buffer_add8(b, k->type);
buffer_add64(b, k->ctime);
buffer_add32(b, k->version);
buffer_add32(b, k->serial);
buffer_add64be(b, k->ctime);
buffer_add32be(b, k->version);
buffer_add32be(b, k->serial);
buffer_add8(b, k->valid);
}
void pcp_seckeyblob(Buffer *b, pcp_key_t *k) {
buffer_add(b, k->masterpub, LEDPUB);
buffer_add(b, k->mastersecret, LEDSEC);
buffer_add(b, k->pub, LBOXPUB);
buffer_add(b, k->secret, LBOXPUB);
buffer_add(b, k->edpub, LEDPUB);
buffer_add(b, k->edsecret, LEDSEC);
buffer_add(b, k->nonce, LNONCE);
buffer_add(b, k->encrypted, LSEC);
buffer_add(b, k->owner, 255);
buffer_add(b, k->mail, 255);
buffer_add(b, k->id, 17);
buffer_add8(b, k->type);
buffer_add64be(b, k->ctime);
buffer_add32be(b, k->version);
buffer_add32be(b, k->serial);
}
pcp_key_t *pcp_blob2key(Buffer *b) {
pcp_key_t *k = ucmalloc(sizeof(pcp_key_t));
buffer_get_chunk(b, k->masterpub, LEDPUB);
buffer_get_chunk(b, k->mastersecret, LEDSEC);
buffer_get_chunk(b, k->pub, LBOXPUB);
buffer_get_chunk(b, k->secret, LBOXPUB);
buffer_get_chunk(b, k->edpub, LEDPUB);
buffer_get_chunk(b, k->edsecret, LEDSEC);
buffer_get_chunk(b, k->nonce, LNONCE);
buffer_get_chunk(b, k->encrypted, LSEC);
buffer_get_chunk(b, k->owner, 255);
buffer_get_chunk(b, k->mail, 255);
buffer_get_chunk(b, k->id, 17);
k->type = buffer_get8(b);
k->ctime = buffer_get64na(b);
k->version = buffer_get32na(b);
k->serial = buffer_get32na(b);
return k;
}
pcp_pubkey_t *pcp_blob2pubkey(Buffer *b) {
pcp_pubkey_t *k = ucmalloc(sizeof(pcp_key_t));
buffer_get_chunk(b, k->masterpub, LEDPUB);
buffer_get_chunk(b, k->pub, LBOXPUB);
buffer_get_chunk(b, k->edpub, LEDPUB);
buffer_get_chunk(b, k->owner, 255);
buffer_get_chunk(b, k->mail, 255);
buffer_get_chunk(b, k->id, 17);
k->type = buffer_get8(b);
k->ctime = buffer_get64na(b);
k->version = buffer_get32na(b);
k->serial = buffer_get32na(b);
k->valid = buffer_get8(b);
return k;
}
Buffer *pcp_keyblob(void *k, int type) {
if(type == PCP_KEY_TYPE_PUBLIC) {
if (type == PCP_KEY_TYPE_PUBLIC) {
Buffer *b = buffer_new(PCP_RAW_PUBKEYSIZE, "bp");
pcp_pubkeyblob(b, (pcp_pubkey_t *)k);
return b;
}
else {
} else {
Buffer *b = buffer_new(PCP_RAW_KEYSIZE, "bs");
pcp_seckeyblob(b, (pcp_key_t *)k);
return b;
}
}
int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key) {
if(key->pub[0] == 0) {
fatal(ptx, "Pubkey sanity check: public key contained in key seems to be empty!\n");
if (key->pub[0] == 0) {
fatal(ptx, "Pubkey sanity check: public key contained in key seems to be "
"empty!\n");
return 1;
}
if(key->type != PCP_KEY_TYPE_PUBLIC) {
fatal(ptx, "Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: %02x)!\n",
PCP_KEY_TYPE_PUBLIC, key->type);
if (key->type != PCP_KEY_TYPE_PUBLIC) {
fatal(ptx,
"Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: "
"%02x)!\n",
PCP_KEY_TYPE_PUBLIC, key->type);
return 1;
}
if(key->version != PCP_KEY_VERSION) {
fatal(ptx, "Pubkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
PCP_KEY_VERSION, key->version);
return 1;
}
if(key->serial <= 0) {
fatal(ptx, "Pubkey sanity check: invalid serial number: %08X!\n", key->serial);
if (key->version != PCP_KEY_VERSION) {
fatal(ptx,
"Pubkey sanity check: unknown key version (expected: %08X, got: "
"%08X)!\n",
PCP_KEY_VERSION, key->version);
return 1;
}
if(key->id[16] != '\0') {
if (key->serial <= 0) {
fatal(ptx, "Pubkey sanity check: invalid serial number: %08X!\n",
key->serial);
return 1;
}
if (key->id[16] != '\0') {
char *got = ucmalloc(17);
memcpy(got, key->id, 17);
got[16] = '\0';
fatal(ptx, "Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
fatal(ptx,
"Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n",
got);
free(got);
return 1;
}
@@ -398,50 +379,63 @@ int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key) {
struct tm *c;
time_t t = (time_t)key->ctime;
c = localtime(&t);
if(c->tm_year <= 0 || c->tm_year > 1100) {
if (c->tm_year <= 0 || c->tm_year > 1100) {
/* well, I'm perhaps overacting here :) */
fatal(ptx, "Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
fatal(ptx,
"Pubkey sanity check: invalid creation timestamp (got year %04d)!\n",
c->tm_year + 1900);
return 1;
}
pcp_pubkey_t *maybe = pcphash_pubkeyexists(ptx, key->id);
if(maybe != NULL) {
fatal(ptx, "Pubkey sanity check: there already exists a key with the id 0x%s\n", key->id);
if (maybe != NULL) {
fatal(ptx,
"Pubkey sanity check: there already exists a key with the id 0x%s\n",
key->id);
return 1;
}
return 0;
}
int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key) {
if(key->encrypted[0] == 0) {
fatal(ptx, "Secretkey sanity check: secret key contained in key seems to be empty!\n");
if (key->encrypted[0] == 0) {
fatal(ptx, "Secretkey sanity check: secret key contained in key seems to "
"be empty!\n");
return 1;
}
if(key->type != PCP_KEY_TYPE_SECRET && key->type != PCP_KEY_TYPE_MAINSECRET) {
fatal(ptx, "Secretkey sanity check: key type is not SECRET (expected: %02x, got: %02x)!\n",
PCP_KEY_TYPE_SECRET, key->type);
if (key->type != PCP_KEY_TYPE_SECRET &&
key->type != PCP_KEY_TYPE_MAINSECRET) {
fatal(ptx,
"Secretkey sanity check: key type is not SECRET (expected: %02x, "
"got: %02x)!\n",
PCP_KEY_TYPE_SECRET, key->type);
return 1;
}
if(key->version != PCP_KEY_VERSION) {
fatal(ptx, "Secretkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
PCP_KEY_VERSION, key->version);
return 1;
}
if(key->serial <= 0) {
fatal(ptx, "Secretkey sanity check: invalid serial number: %08X!\n", key->serial);
if (key->version != PCP_KEY_VERSION) {
fatal(ptx,
"Secretkey sanity check: unknown key version (expected: %08X, got: "
"%08X)!\n",
PCP_KEY_VERSION, key->version);
return 1;
}
if(key->id[16] != '\0') {
if (key->serial <= 0) {
fatal(ptx, "Secretkey sanity check: invalid serial number: %08X!\n",
key->serial);
return 1;
}
if (key->id[16] != '\0') {
char *got = ucmalloc(17);
memcpy(got, key->id, 17);
got[16] = '\0';
fatal(ptx, "Secretkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
fatal(ptx,
"Secretkey sanity check: invalid key id (expected 16 bytes, got: "
"%s)!\n",
got);
free(got);
return 1;
}
@@ -449,15 +443,21 @@ int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key) {
struct tm *c;
time_t t = (time_t)key->ctime;
c = localtime(&t);
if(c->tm_year <= 70 || c->tm_year > 1100) {
if (c->tm_year <= 70 || c->tm_year > 1100) {
/* well, I'm perhaps overacting here :) */
fatal(ptx, "Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
fatal(
ptx,
"Secretkey sanity check: invalid creation timestamp (got year %04d)!\n",
c->tm_year + 1900);
return 1;
}
pcp_key_t *maybe = pcphash_keyexists(ptx, key->id);
if(maybe != NULL) {
fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", key->id);
if (maybe != NULL) {
fatal(
ptx,
"Secretkey sanity check: there already exists a key with the id 0x%s\n",
key->id);
return 1;
}
@@ -465,40 +465,48 @@ int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key) {
}
void pcp_dumpkey(pcp_key_t *k) {
int i;
unsigned int i;
printf("Dumping pcp_key_t raw values:\n");
printf("masterpub: ");
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->masterpub[i]);
for (i = 0; i < LEDPUB; ++i)
printf("%02x", (unsigned int)k->masterpub[i]);
printf("\n");
printf(" public: ");
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->pub[i]);
for (i = 0; i < LBOXPUB; ++i)
printf("%02x", (unsigned int)k->pub[i]);
printf("\n");
printf(" edpub: ");
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->edpub[i]);
for (i = 0; i < LEDPUB; ++i)
printf("%02x", (unsigned int)k->edpub[i]);
printf("\n");
printf("mastersec: ");
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->mastersecret[i]);
for (i = 0; i < LEDSEC; ++i)
printf("%02x", (unsigned int)k->mastersecret[i]);
printf("\n");
printf(" secret: ");
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->secret[i]);
for (i = 0; i < LBOXPUB; ++i)
printf("%02x", (unsigned int)k->secret[i]);
printf("\n");
printf(" edsecret: ");
for ( i = 0;i < 64;++i) printf("%02x",(unsigned int) k->edsecret[i]);
for (i = 0; i < LEDSEC; ++i)
printf("%02x", (unsigned int)k->edsecret[i]);
printf("\n");
printf(" nonce: ");
for ( i = 0;i < 24;++i) printf("%02x",(unsigned int) k->nonce[i]);
for (i = 0; i < LNONCE; ++i)
printf("%02x", (unsigned int)k->nonce[i]);
printf("\n");
printf("encrypted: ");
for ( i = 0;i < 80;++i) printf("%02x",(unsigned int) k->encrypted[i]);
for (i = 0; i < LSEC; ++i)
printf("%02x", (unsigned int)k->encrypted[i]);
printf("\n");
printf(" owner: %s\n", k->owner);
@@ -516,21 +524,23 @@ void pcp_dumpkey(pcp_key_t *k) {
printf(" type: 0x%02X\n", k->type);
}
void pcp_dumppubkey(pcp_pubkey_t *k) {
int i;
unsigned int i;
printf("Dumping pcp_pubkey_t raw values:\n");
printf("masterpub: ");
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->masterpub[i]);
for (i = 0; i < LEDPUB; ++i)
printf("%02x", (unsigned int)k->masterpub[i]);
printf("\n");
printf(" public: ");
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->pub[i]);
for (i = 0; i < LBOXPUB; ++i)
printf("%02x", (unsigned int)k->pub[i]);
printf("\n");
printf(" edpub: ");
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) k->edpub[i]);
for (i = 0; i < LEDPUB; ++i)
printf("%02x", (unsigned int)k->edpub[i]);
printf("\n");
printf(" owner: %s\n", k->owner);
@@ -547,3 +557,37 @@ void pcp_dumppubkey(pcp_pubkey_t *k) {
printf(" type: 0x%02X\n", k->type);
}
/*
via
http://rosettacode.org/wiki/Entropy#C
*/
double pcp_getentropy(char *source) {
int len;
int *hist;
double H;
int wherechar[256];
int i, histlen;
histlen = 0;
H = 0;
len = (int)strlen(source);
hist = (int *)calloc(len, sizeof(int));
for (i = 0; i < 256; i++)
wherechar[i] = -1;
for (i = 0; i < len; i++) {
if (wherechar[(int)source[i]] == -1) {
wherechar[(int)source[i]] = histlen;
histlen++;
}
hist[wherechar[(int)source[i]]]++;
}
for (i = 0; i < histlen; i++) {
H -= (double)hist[i] / len * log2((double)hist[i] / len);
}
return H;
}

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein
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,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -22,39 +22,21 @@
#include "keysig.h"
pcp_keysig_t * keysig2be(pcp_keysig_t *s) {
#ifdef __CPU_IS_BIG_ENDIAN
return s;
#else
uint32_t size = s->size;
byte* p = (byte*)&size;
if(p[0] != 0) {
s->size = htobe32(s->size);
}
return s;
#endif
}
pcp_keysig_t *keysig2native(pcp_keysig_t *s) {
#ifdef __CPU_IS_BIG_ENDIAN
return s;
#else
s->size = be32toh(s->size);
return s;
#endif
}
Buffer *pcp_keysig2blob(pcp_keysig_t *s) {
Buffer *b = buffer_new(256, "keysig2blob");
void pcp_keysig2blob(Buffer *b, pcp_keysig_t *s) {
buffer_add8(b, s->type);
buffer_add32be(b, s->size);
buffer_add(b, s->id, 17);
buffer_add(b, s->checksum, 32);
buffer_add(b, s->checksum, LSHA);
buffer_add(b, s->blob, s->size);
}
Buffer *pcp_keysigblob(pcp_keysig_t *s) {
Buffer *b = buffer_new(256, "keysig2blob");
pcp_keysig2blob(b, s);
return b;
}
pcp_keysig_t *pcp_keysig_new(Buffer *blob) {
pcp_keysig_t *pcp_blob2keysig(Buffer *blob) {
pcp_keysig_t *sk = ucmalloc(sizeof(pcp_keysig_t));
uint8_t type = buffer_get8(blob);
@@ -62,17 +44,17 @@ pcp_keysig_t *pcp_keysig_new(Buffer *blob) {
buffer_get_chunk(blob, sk->id, 17);
byte *checksum = ucmalloc(32);
buffer_get_chunk(blob, checksum, 32);
byte *checksum = ucmalloc(LSHA);
buffer_get_chunk(blob, checksum, LSHA);
sk->blob = ucmalloc(size);
buffer_get_chunk(blob, sk->blob, size);
sk->size = size;
sk->type = type;
memcpy(sk->checksum, checksum, 32);
memcpy(sk->checksum, checksum, LSHA);
ucfree(checksum, 32);
ucfree(checksum, LSHA);
return sk;
}
@@ -86,7 +68,7 @@ void pcp_dumpkeysig(pcp_keysig_t *s) {
printf(" size: %ld\n", (long int)s->size);
printf(" checksum: ");
for ( i = 0;i < 32;++i) printf("%02x",(unsigned int) s->checksum[i]);
for ( i = 0;i < LSHA;++i) printf("%02x",(unsigned int) s->checksum[i]);
printf("\n");
_dump(" blob:", s->blob, s->size);

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -83,7 +83,7 @@ void *ucrealloc(void *d, size_t oldlen, size_t newlen) {
byte *value = realloc (d, newlen);
if (value == NULL) {
err(errno, "Cannot reallocate %ld bytes of memory", newlen);
err(errno, "Cannot reallocate %"FMT_SIZE_T" bytes of memory", (SIZE_T_CAST)newlen);
exit(-1);
}

64
libpcp/meson.build Normal file
View File

@@ -0,0 +1,64 @@
# -*-python-*-
libincludes = include_directories('include', 'include/pcp')
# check for libraries with CMAKE or pkg-config
sodium = dependency('libsodium')
# manually check for libraries
jansson = c.find_library('jansson', required: true,
dirs : ['/usr', '/usr/local'])
conf.set('HAVE_SODIUM', sodium.found())
conf.set('HAVE_JSON', jansson.found())
math = c.find_library('m')
# add dependencies, manual libs are added directly below
pcp_deps = [
sodium, jansson, math
]
libpcp = shared_library(
'pcp',
'buffer.c',
'context.c',
'crypto.c',
'ed.c',
'getpass.c',
'jenhash.c',
'key.c',
'keyhash.c',
'keysig.c',
'mem.c',
'mgmt.c',
'pcpstream.c',
'platform.c',
'randomart.c',
'readpass.c',
'scrypt.c',
'util.c',
'vault.c',
'version.c',
'z85.c',
'zmq_z85.c',
include_directories: libincludes,
install: true,
dependencies: pcp_deps
)
libpcp_dep = declare_dependency(
include_directories: libincludes,
link_with: libpcp,
)
# write out the config header
m = configure_file(
input : 'config.h.in',
output : 'config.h',
configuration : conf,
)

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2015 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -103,18 +103,18 @@ void ps_rewind(Pcpstream *stream, void *buf, size_t bufsize) {
size_t ps_read_raw(Pcpstream *stream, void *buf, size_t readbytes) {
size_t gotbytes = 0;
size_t idx = 0;
if(buffer_left(stream->save) > 0) {
/* something left from last rewind, first use this */
if(buffer_left(stream->save) >= readbytes) {
gotbytes = buffer_get_chunk(stream->save, buf, readbytes);
if(buffer_left(stream->save) == 0)
buffer_clear(stream->save);
buffer_clear(stream->save);
goto rawdone;
}
else {
/* fetch the remainder of the save buffer, remember how much
to fetch from source next */
to fetch from source next */
idx = buffer_get_chunk(stream->save, buf, buffer_left(stream->save));
buffer_clear(stream->save);
readbytes -= idx;
@@ -137,6 +137,7 @@ size_t ps_read_raw(Pcpstream *stream, void *buf, size_t readbytes) {
}
else {
size_t got = fread(buf+idx, 1, readbytes, stream->fd);
gotbytes += got;
if(feof(stream->fd) != 0)
stream->eof = 1;
@@ -146,7 +147,8 @@ size_t ps_read_raw(Pcpstream *stream, void *buf, size_t readbytes) {
rawdone:
//_dump("ps_read_raw", buf, gotbytes);
//_dump(" ps_read_raw first byte:", buf, 1);
//fprintf(stderr, " ps_read_raw, gotbytes: %ld\n", gotbytes);
return gotbytes;
}
@@ -157,10 +159,10 @@ size_t ps_read_raw(Pcpstream *stream, void *buf, size_t readbytes) {
size_t ps_read_cached(Pcpstream *stream, void *buf, size_t readbytes) {
/*
fprintf(stderr, "%ld <= %ld && %ld <= %ld\n",
readbytes, buffer_left(stream->cache), readbytes, stream->blocksize) ;
readbytes, buffer_left(stream->cache), readbytes, stream->blocksize) ;
fprintf(stderr, "%d == 1 && %ld >= %ld\n",
ps_end(stream), readbytes, buffer_left(stream->cache));
ps_end(stream), readbytes, buffer_left(stream->cache));
*/
if(readbytes <= buffer_left(stream->cache) && readbytes <= stream->blocksize) {
/* enough left in current cache */
@@ -173,7 +175,8 @@ size_t ps_read_cached(Pcpstream *stream, void *buf, size_t readbytes) {
}
else {
// fprintf(stderr, " fetch next\n");
/* request for chunk larger than what we've got in the cache */
/* request for chunk larger than what we've got in the cache */
// FIXME: use static buffer !
Buffer *tmp = buffer_new(stream->blocksize, "Pcpreadchunktmp");
if( buffer_left(stream->cache) > 0) {
@@ -191,35 +194,35 @@ size_t ps_read_cached(Pcpstream *stream, void *buf, size_t readbytes) {
/* not enough cached, fetch the next chunk */
// fprintf(stderr, " fetch next read_next\n");
if(ps_read_next(stream) == 0)
break;
break;
// fprintf(stderr, " fetch next read_continue\n");
/* need to fetch more? */
left = readbytes - (buffer_size(tmp) + buffer_size(stream->next));
if(left < 0) {
/* no more to fetch, in fact there's more than we need */
/* determine overlapping bytes */
size_t overlap = readbytes - buffer_size(tmp);
/* no more to fetch, in fact there's more than we need */
/* determine overlapping bytes */
size_t overlap = readbytes - buffer_size(tmp);
/* avoid overflow */
if(overlap > buffer_size(stream->next))
overlap = buffer_size(stream->next);
/* avoid overflow */
if(overlap > buffer_size(stream->next))
overlap = buffer_size(stream->next);
/* add the overlap from next to tmp */
buffer_get_chunk_tobuf(stream->next, tmp, overlap);
/* add the overlap from next to tmp */
buffer_get_chunk_tobuf(stream->next, tmp, overlap);
/* move the rest of stream->next into cache */
buffer_clear(stream->cache);
buffer_get_chunk_tobuf(stream->next, stream->cache, buffer_left(stream->next));
buffer_clear(stream->next);
/* move the rest of stream->next into cache */
buffer_clear(stream->cache);
buffer_get_chunk_tobuf(stream->next, stream->cache, buffer_left(stream->next));
buffer_clear(stream->next);
}
else {
/* we've got precisely what we need, no need to calculate any overlap
OR there's more to fetch, we don't have enough stuff yet,
put next into tmp, reset next and loop again - same behavior */
buffer_add_buf(tmp, stream->next);
buffer_clear(stream->next);
/* we've got precisely what we need, no need to calculate any overlap
OR there's more to fetch, we don't have enough stuff yet,
put next into tmp, reset next and loop again - same behavior */
buffer_add_buf(tmp, stream->next);
buffer_clear(stream->next);
}
}
@@ -257,6 +260,7 @@ size_t ps_read(Pcpstream *stream, void *buf, size_t readbytes) {
size_t got = 0;
if(stream->cache == NULL) {
got = ps_read_raw(stream, buf, readbytes);
// fprintf(stderr, "%ld = ps_read_raw(stream, buf, readbytes); // no cache\n", got);
}
else if(buffer_size(stream->cache) > 0) {
/* use cache */
@@ -274,26 +278,27 @@ size_t ps_read(Pcpstream *stream, void *buf, size_t readbytes) {
}
else if(stream->armor == 1) {
/* z85 encoding has already been determined, therefore the cache
is now filled, use it then */
is now filled, use it then */
got = ps_read_cached(stream, buf, readbytes);
// fprintf(stderr, "%ld = ps_read_cached(stream, buf, readbytes);\n", got);
}
else {
/* read directly from source */
got = ps_read_raw(stream, buf, readbytes);
// fprintf(stderr, "%ld = ps_read_raw(stream, buf, readbytes);\n", got);
}
}
stream->pos += got;
// fprintf(stderr, " ps_read(): %ld\n", got);
//fprintf(stderr, " ps_read(): %ld\n", got);
return got;
}
int ps_readline(Pcpstream *stream, Buffer *line) {
int c = -1, max = 1;
byte b[1];
while(c<PSMAXLINE) {
while(c<PSMAXLINE) { // && ps_end(stream) != 1
//fprintf(stderr, " ps_readline: call raw\n");
if(ps_read_raw(stream, b, 1) < 1) {
//fprintf(stderr, " ps_readline: raw returned < 1\n");
@@ -304,7 +309,7 @@ int ps_readline(Pcpstream *stream, Buffer *line) {
//fprintf(stderr, " ps_readline: raw found CR\n");
continue;
}
else if(*b == '\n' || ps_end(stream) == 1) {
else if(*b == '\n') {
//fprintf(stderr, " ps_readline: raw found NL\n");
c++;
max = 0;
@@ -326,7 +331,8 @@ int ps_readline(Pcpstream *stream, Buffer *line) {
return -1;
}
// fprintf(stderr, " ps_readline: raw return %d\n", c);
//fprintf(stderr, " ps_readline: raw return %d, last b: <%c>\n", c, b[0]);
//buffer_info(line);
return c;
}
@@ -389,61 +395,63 @@ size_t ps_read_decode(Pcpstream *stream) {
while(buffer_size(z) < stream->blocksize) {
buffer_clear(line);
if(ps_readline(stream, line) >= 0) {
//fprintf(stderr, "got: <%s>\n", buffer_get_str(line));
if(z85_isbegin(line) && stream->have_begin == 0) {
/* begin header encountered */
stream->have_begin = 1; /* otherwise ignore it */
continue;
}
else if(z85_isend(line)) {
/* end header encountered */
break;
}
else if(z85_isempty(line)) {
/* ignore empty lines */
continue;
}
else {
/* regular z85 encoded content */
// fprintf(stderr, "regular\n");
// fprintf(stderr, " %ld + %ld > %ld\n", buffer_size(z), buffer_size(line), stream->blocksize);
if(buffer_size(z) + buffer_size(line) > stream->blocksize) {
/* we've got more than needed.
put what we need into z and the remainder
into the save buffer for further reading. */
/* fprintf(stderr, "overflow %ld + %ld > %ld\n",
buffer_size(z), buffer_size(line), stream->blocksize);
*/
buffer_get_chunk_tobuf(line, z, stream->blocksize - buffer_size(z));
buffer_get_chunk_tobuf(line, stream->save, buffer_left(line));
if(!ps_left(stream)) {
/* only add the newline if there's no more to follow */
buffer_add8(stream->save, '\n');
}
break;
}
else {
/* not enough yet, store it and go on */
buffer_add_buf(z, line);
}
}
//fprintf(stderr, "got: <%s>\n", buffer_get_str(line));
if(z85_isbegin(line) && stream->have_begin == 0) {
/* begin header encountered */
stream->have_begin = 1; /* otherwise ignore it */
continue;
}
else if(z85_isend(line)) {
/* end header encountered */
break;
}
else if(z85_isempty(line)) {
/* ignore empty lines */
continue;
}
else {
/* regular z85 encoded content */
// fprintf(stderr, "regular\n");
// fprintf(stderr, " %ld + %ld > %ld\n", buffer_size(z), buffer_size(line), stream->blocksize);
if(buffer_size(z) + buffer_size(line) > stream->blocksize) {
/* we've got more than needed.
put what we need into z and the remainder
into the save buffer for further reading. */
/* fprintf(stderr, "overflow %ld + %ld > %ld\n",
buffer_size(z), buffer_size(line), stream->blocksize);
*/
buffer_get_chunk_tobuf(line, z, stream->blocksize - buffer_size(z));
buffer_get_chunk_tobuf(line, stream->save, buffer_left(line));
if(!ps_left(stream)) {
/* only add the newline if there's no more to follow */
buffer_add8(stream->save, '\n');
}
break;
}
else {
/* not enough yet, store it and go on */
buffer_add_buf(z, line);
}
}
}
else {
// fprintf(stderr, " ps_read_next readline returned 0\n");
/* eof or err */
break;
// fprintf(stderr, " ps_read_next readline returned 0\n");
/* eof or err */
break;
}
}
}
//fprintf(stderr, "%s\n", buffer_get_str(z));
//buffer_info(z);
//buffer_dump(z);
//fprintf(stderr, "\n%s\n", buffer_get_str(z));
/* finally, decode it and put into next */
size_t binlen, outlen;
byte *bin = pcp_z85_decode(ptx, buffer_get_str(z), &binlen);
//fprintf(stderr, "ps_read_decode decoding z: %ld, got: %ld\n", buffer_size(z), binlen);
//_dump("bin", bin, binlen);
//fatals_ifany();
fatals_ifany(ptx);
if(bin == NULL) {
/* it's not z85 encoded, so threat it as binary */
@@ -495,15 +503,15 @@ size_t ps_write(Pcpstream *stream, void *buf, size_t writebytes) {
buffer_add_buf(tmp, stream->cache);
while (buffer_left(tmp) > stream->blocksize) {
/* iterate over tmp blockwise, encode each block, write it out until there's a rest */
buffer_clear(stream->cache);
buffer_get_chunk_tobuf(tmp, stream->cache, stream->blocksize);
ps_write_encode(stream, z);
/* iterate over tmp blockwise, encode each block, write it out until there's a rest */
buffer_clear(stream->cache);
buffer_get_chunk_tobuf(tmp, stream->cache, stream->blocksize);
ps_write_encode(stream, z);
}
/* now, z contains a couple of z85 encoded blocks, tmp contains the
remainder of the write buffer, store the rest in the cache and
go on as nothing did happen */
remainder of the write buffer, store the rest in the cache and
go on as nothing did happen */
buffer_clear(stream->cache);
buffer_add(stream->cache, buffer_get_remainder(tmp), buffer_left(tmp));
buffer_free(tmp);
@@ -515,14 +523,14 @@ size_t ps_write(Pcpstream *stream, void *buf, size_t writebytes) {
void *aside = NULL;
size_t overlap = (buffer_size(stream->cache) + writebytes) - stream->blocksize;
if(overlap > 0) {
/* yes, store the overlap, put the left part into the cache */
aside = ucmalloc(overlap);
memcpy(aside, buf + (writebytes - overlap), overlap); /* FIXME: check if this works */
buffer_add(stream->cache, buf, writebytes - overlap);
/* yes, store the overlap, put the left part into the cache */
aside = ucmalloc(overlap);
memcpy(aside, buf + (writebytes - overlap), overlap); /* FIXME: check if this works */
buffer_add(stream->cache, buf, writebytes - overlap);
}
else {
/* cache+buf == blocksize */
buffer_add(stream->cache, buf, writebytes);
/* cache+buf == blocksize */
buffer_add(stream->cache, buf, writebytes);
}
/* encode the cache into z */
@@ -530,10 +538,10 @@ size_t ps_write(Pcpstream *stream, void *buf, size_t writebytes) {
buffer_clear(stream->cache);
if(aside != NULL) {
/* there is an overlapping rest, put it into the cache
the caller needs to call ps_finish() to put it out */
buffer_add(stream->cache, aside, overlap);
free(aside);
/* there is an overlapping rest, put it into the cache
the caller needs to call ps_finish() to put it out */
buffer_add(stream->cache, aside, overlap);
free(aside);
}
}
}
@@ -637,7 +645,7 @@ void ps_close(Pcpstream *stream) {
if(stream->cache != NULL) {
if(stream->is_output == 1) {
if(buffer_left(stream->cache) != 0)
buffer_info(stream->cache);
buffer_info(stream->cache);
assert(buffer_left(stream->cache) == 0); /* there's something left in the cache, call ps_finish() */
}
buffer_free(stream->cache);

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -32,6 +32,12 @@ void err(int eval, const char *fmt, ...) {
}
fprintf(stderr, ": %s\n", strerror(errno));
va_end(ap);
/* from the FreeBSD err() manpage:
The err(), verr(), errc(), verrc(), errx(), and verrx() functions do not
return, but exit with the value of the argument eval.
*/
exit(eval);
}
#endif
@@ -48,9 +54,9 @@ int vasprintf(char **ret, const char *format, va_list args) {
if (buffer != NULL) {
count = vsnprintf(buffer, count + 1, format, copy);
if (count < 0)
free(buffer);
free(buffer);
else
*ret = buffer;
*ret = buffer;
}
}
va_end(copy); /* Each va_start() or va_copy() needs a va_end() */
@@ -86,11 +92,11 @@ strnstr(const char *s, const char *find, size_t slen)
len = strlen(find);
do {
do {
if (slen-- < 1 || (sc = *s++) == '\0')
return (NULL);
if (slen-- < 1 || (sc = *s++) == '\0')
return (NULL);
} while (sc != c);
if (len > slen)
return (NULL);
return (NULL);
} while (strncmp(s, find, len) != 0);
s--;
}

278
libpcp/readpass.c Normal file
View File

@@ -0,0 +1,278 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Modifications (c) 2013 - 2015 by T.v.Dein, same license as this file.
*/
#include "readpass.h"
/**
* tarsnap_getpass(passwd, prompt, confirmprompt, devtty)
* If ${devtty} is non-zero, read a password from /dev/tty if possible; if
* not, read from stdin. If reading from a tty (either /dev/tty or stdin),
* disable echo and prompt the user by printing ${prompt} to stderr. If
* ${confirmprompt} is non-NULL, read a second password (prompting if a
* terminal is being used) and repeat until the user enters the same password
* twice. Return the password as a malloced NUL-terminated string via
* ${passwd}. The obscure name is to avoid namespace collisions due to the
* getpass / readpass / readpassphrase / etc. functions in various libraries.
*/
int
pcp_readpass(PCPCTX *ptx, char ** passwd, const char * prompt,
const char * confirmprompt, int devtty, char *readfromfile)
{
FILE * readfrom;
char passbuf[MAXPASSLEN];
char confpassbuf[MAXPASSLEN];
struct termios term, term_old;
int usingtty;
/*
* If devtty != 0, try to open /dev/tty; if that fails, or if devtty
* is zero, we'll read the password from stdin instead.
*
* Added by tlinden: however, if readfromfile is defined, we'll
* read the password from there, but if it is '-' we'll use stdin
* as well.
*/
if ((devtty == 0) || ((readfrom = fopen("/dev/tty", "r")) == NULL)) {
if(readfromfile != NULL) {
// FIXME: check if readfromfile is executable,
// if yes, call askextpass(tobewritten) and
// read from the returned fd somehow
if(readfromfile[0] == '-') {
readfrom = stdin;
}
else {
if((readfrom = fopen(readfromfile, "r")) == NULL) {
fatal(ptx, "Could not open password file '%s'\n", readfromfile);
goto err1;
}
}
}
else {
readfrom = stdin;
}
}
/* If we're reading from a terminal, try to disable echo. */
if ((usingtty = isatty(fileno(readfrom))) != 0) {
if (tcgetattr(fileno(readfrom), &term_old)) {
fatal(ptx, "Cannot read terminal settings\n");
goto err1;
}
memcpy(&term, &term_old, sizeof(struct termios));
term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL;
if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
fatal(ptx, "Cannot set terminal settings\n");
goto err1;
}
}
retry:
/* If we have a terminal, prompt the user to enter the password. */
if (usingtty)
fprintf(stderr, "%s: ", prompt);
/* Read the password. */
if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
fatal(ptx, "Cannot read password\n");
goto err2;
}
/* Confirm the password if necessary. */
if (confirmprompt != NULL) {
if (usingtty)
fprintf(stderr, "%s: ", confirmprompt);
if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) {
fatal(ptx, "Cannot read password\n");
goto err2;
}
if (strcmp(passbuf, confpassbuf)) {
fprintf(stderr,
"Passwords mismatch, please try again\n");
goto retry;
}
}
/* Terminate the string at the first "\r" or "\n" (if any). */
passbuf[strcspn(passbuf, "\r\n")] = '\0';
/* enforce no empty passwords */
if (strnlen(passbuf, MAXPASSLEN) == 0) {
fprintf(stderr,
"Empty password not allowed, please try again\n");
goto retry;
}
/* If we changed terminal settings, reset them. */
if (usingtty)
tcsetattr(fileno(readfrom), TCSANOW, &term_old);
/* Close /dev/tty if we opened it.
if readfromfile is defined and set to -, disable stdin */
if (readfrom != stdin) {
fclose(readfrom);
}
/* Copy the password out. */
char *p = smalloc(strlen(passbuf) + 1);
memcpy(p, passbuf, strlen(passbuf) + 1 );
*passwd = p;
/* Zero any stored passwords. */
memset(passbuf, 0, MAXPASSLEN);
memset(confpassbuf, 0, MAXPASSLEN);
/* Success! */
return (0);
err2:
/* Reset terminal settings if necessary. */
if (usingtty)
tcsetattr(fileno(readfrom), TCSAFLUSH, &term_old);
err1:
/* Close /dev/tty if we opened it. */
if (readfrom != stdin)
fclose(readfrom);
/* Failure! */
return (-1);
}
/*****************************************************************************
* Author: Valient Gough <vgough@pobox.com>
*
*****************************************************************************
* Copyright (c) 2004, Valient Gough
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* modified by tlinden@cpan.org (c++ => c, pcp api)
*/
int pcp_readpass_fromprog(PCPCTX *ptx, char **passwd, const char *askpass) {
// have a child process run the command and get the result back to us.
int fds[2], pid;
int res;
char passbuf[MAXPASSLEN];
res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
if (res == -1) {
fatal(ptx, "Internal error: socketpair() failed");
goto aerr1;
}
pid = fork();
if (pid == -1) {
fatal( ptx, "Internal error: fork() failed");
close(fds[0]);
close(fds[1]);
goto aerr1;
}
if (pid == 0) {
const char *argv[4];
argv[0] = "/bin/sh";
argv[1] = "-c";
argv[2] = askpass;
argv[3] = 0;
// child process.. run the command and send output to fds[0]
close(fds[1]); // we don't use the other half..
// make a copy of stdout and stderr descriptors, and set an environment
// variable telling where to find them, in case a child wants it..
int stdOutCopy = dup(STDOUT_FILENO);
int stdErrCopy = dup(STDERR_FILENO);
// replace STDOUT with our socket, which we'll used to receive the
// password..
dup2(fds[0], STDOUT_FILENO);
// ensure that STDOUT_FILENO and stdout/stderr are not closed on exec..
fcntl(STDOUT_FILENO, F_SETFD, 0); // don't close on exec..
fcntl(stdOutCopy, F_SETFD, 0);
fcntl(stdErrCopy, F_SETFD, 0);
char tmpBuf[8];
snprintf(tmpBuf, sizeof(tmpBuf) - 1, "%i", stdOutCopy);
setenv("PCP_ENV_STDOUT", tmpBuf, 1);
snprintf(tmpBuf, sizeof(tmpBuf) - 1, "%i", stdErrCopy);
setenv("PCP_ENV_STDERR", tmpBuf, 1);
execvp(argv[0], (char *const *)argv); // returns only on error..
fatal(ptx, "Internal error: failed to exec program");
goto aerr1;
}
close(fds[0]);
memset(passbuf, 0, MAXPASSLEN);
if ( recv(fds[1], passbuf, MAXPASSLEN, 0) <= 0) {
fatal(ptx, "Cannot read password\n");
goto aerr1;
}
close(fds[1]);
waitpid(pid, NULL, 0);
/* Terminate the string at the first "\r" or "\n" (if any). */
passbuf[strcspn(passbuf, "\r\n")] = '\0';
/* Copy the password out. */
char *p = smalloc(strlen(passbuf) + 1);
memcpy(p, passbuf, strlen(passbuf) + 1 );
*passwd = p;
/* Zero any stored passwords. */
memset(passbuf, 0, MAXPASSLEN);
return 0;
aerr1:
return -1;
}

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -30,8 +30,8 @@ byte* pcp_scrypt(PCPCTX *ptx, char *passwd, size_t passwdlen, byte *nonce, size_
nonce, noncelen, NULL, 0);
int status = crypto_pwhash_scryptsalsa208sha256(dk, 64, passwd, passwdlen, salt,
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE,
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE);
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE,
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE);
ucfree(salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
if (status == 0) {

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T. von Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -69,7 +69,7 @@ void _dump(char *n, byte *d, size_t s) {
if(i % 36 == 35 && i > 0) {
fprintf(stderr, "\n");
for(c=0; c<l; ++c)
fprintf(stderr, " ");
fprintf(stderr, " ");
}
}
fprintf(stderr, "\n");
@@ -119,3 +119,114 @@ size_t _hex2bin(const char *hex_str, unsigned char *byte_array, size_t byte_arra
return byte_array_size;
}
/*
* Convert byte arrays from big endian to numbers and vice versa. Do
* not take care about host endianess. In Rob Pikes' words:
* https://commandcenter.blogspot.de/2012/04/byte-order-fallacy.html
*
* With this, we remove all calls to byte swap functions like b64toh
* and the likes. They are problematic and I really hated the ifdef
* mess in platform.h anyway.
*/
uint64_t _wireto64(byte *data) {
uint64_t i =
((uint64_t)data[7]<<0) |
((uint64_t)data[6]<<8) |
((uint64_t)data[5]<<16) |
((uint64_t)data[4]<<24) |
((uint64_t)data[3]<<32) |
((uint64_t)data[2]<<40) |
((uint64_t)data[1]<<48) |
((uint64_t)data[0]<<56);
return i;
}
uint32_t _wireto32(byte *data) {
uint32_t i =
((uint32_t)data[3]<<0) |
((uint32_t)data[2]<<8) |
((uint32_t)data[1]<<16) |
((uint32_t)data[0]<<24);
return i;
}
uint16_t _wireto16(byte *data) {
uint16_t i =
((uint16_t)data[1]<<0) |
((uint16_t)data[0]<<8);
return i;
}
void _64towire(uint64_t i, byte *data) {
data[0] = (i >> 56) & 0xFF;
data[1] = (i >> 48) & 0xFF;
data[2] = (i >> 40) & 0xFF;
data[3] = (i >> 32) & 0xFF;
data[4] = (i >> 24) & 0xFF;
data[5] = (i >> 16) & 0xFF;
data[6] = (i >> 8) & 0xFF;
data[7] = i & 0xFF;
}
void _32towire(uint32_t i, byte *data) {
data[0] = (i >> 24) & 0xFF;
data[1] = (i >> 16) & 0xFF;
data[2] = (i >> 8) & 0xFF;
data[3] = i & 0xFF;
}
void _16towire(uint16_t i, byte *data) {
data[0] = (i >> 8) & 0xFF;
data[1] = i & 0xFF;
}
/* via https://github.com/chmike/cst_time_memcmp
Licensed as:
The MIT License (MIT)
Copyright (c) 2015 Christophe Meessen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This is the safest1 variant using subscriptions.
*/
int cst_time_memcmp(const void *m1, const void *m2, size_t n) {
int res = 0, diff;
if (m1 != m2 && n && m1 && m2) {
const unsigned char *pm1 = (const unsigned char *)m1;
const unsigned char *pm2 = (const unsigned char *)m2;
do {
--n;
diff = pm1[n] - pm2[n];
res = (res & (((diff - 1) & ~diff) >> 8)) | diff;
} while (n != 0);
}
return ((res - 1) >> 8) + (res >> 8) + 1;
}

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -29,15 +29,15 @@ vault_t *pcpvault_init(PCPCTX *ptx, char *filename) {
if(vault != NULL) {
if(vault->isnew == 1) {
if(pcpvault_create(ptx, vault) != 0) {
pcpvault_close(ptx, vault);
return NULL;
pcpvault_close(ptx, vault);
return NULL;
}
}
else {
if(pcpvault_fetchall(ptx, vault) != 0) {
errno = 0; /* weird, something sets it to ENOENT and it's not me */
pcpvault_close(ptx, vault);
return NULL;
errno = 0; /* weird, something sets it to ENOENT and it's not me */
pcpvault_close(ptx, vault);
return NULL;
}
}
}
@@ -57,7 +57,7 @@ vault_t *pcpvault_new(PCPCTX *ptx, char *filename, int is_tmp) {
b = arc4random();
snprintf(vault->filename, 1024, "%s-%08x%08x", filename, a, b);
if (stat (vault->filename, &stat_buf) != 0)
break;
break;
}
unlink(vault->filename);
vault->size = 0;
@@ -111,7 +111,7 @@ int pcpvault_create(PCPCTX *ptx, vault_t *vault) {
header->version = PCP_VAULT_VERSION;
vault->version = header->version;
memcpy(vault->checksum, header->checksum, 32);
memcpy(vault->checksum, header->checksum, LSHA);
vh2be(header);
@@ -164,9 +164,7 @@ int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) {
itemsize = PCP_RAW_PUBKEYSIZE;
saveitem = ucmalloc(sizeof(pcp_pubkey_t));
memcpy(saveitem, item, sizeof(pcp_pubkey_t));
pubkey2be((pcp_pubkey_t *)item);
blob = buffer_new(PCP_RAW_KEYSIZE, "bs");
pcp_pubkeyblob(blob, (pcp_pubkey_t *)item);
blob = pcp_keyblob(item, type);
}
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
saveitem = ucmalloc(sizeof(pcp_keysig_t));
@@ -176,16 +174,14 @@ int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) {
memcpy(ksout, ksin, sizeof(pcp_keysig_t));
ksout->blob = ucmalloc(ksin->size);
memcpy(ksout->blob, ksin->blob, ksin->size);
blob = pcp_keysig2blob(item);
blob = pcp_keysigblob(ksin);
itemsize = buffer_size(blob);
}
else {
itemsize = PCP_RAW_KEYSIZE;
saveitem = ucmalloc(sizeof(pcp_key_t));
memcpy(saveitem, item, sizeof(pcp_key_t));
key2be((pcp_key_t *)item);
blob = pcp_keyblob(item, type);
pcp_seckeyblob(blob, (pcp_key_t *)item);
}
if(tmp != NULL) {
@@ -224,27 +220,43 @@ int pcpvault_writeall(PCPCTX *ptx, vault_t *vault) {
if(tmp != NULL) {
if(pcpvault_create(ptx, tmp) == 0) {
pcp_key_t *k = NULL;
Buffer *blob = buffer_new(PCP_RAW_PUBKEYSIZE, "bs");
pcphash_iterate(ptx, k) {
pcp_seckeyblob(blob, k);
if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_KEYSIZE, PCP_KEY_TYPE_SECRET) != 0) {
buffer_free(blob);
goto errwa;
}
buffer_clear(blob);
}
pcp_pubkey_t *p = NULL;
pcphash_iteratepub(ptx, p) {
pcp_pubkeyblob(blob, p);
if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_PUBKEYSIZE, PCP_KEY_TYPE_PUBLIC) != 0) {
buffer_free(blob);
goto errwa;
}
buffer_clear(blob);
pcp_keysig_t *s = NULL;
Buffer *blob = buffer_new(PCP_RAW_PUBKEYSIZE, "bs");
pcphash_iterate(ptx, k) {
pcp_seckeyblob(blob, k);
if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_KEYSIZE,
PCP_KEY_TYPE_SECRET) != 0) {
buffer_free(blob);
goto errwa;
}
buffer_clear(blob);
}
pcphash_iteratepub(ptx, p) {
pcp_pubkeyblob(blob, p);
if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_PUBKEYSIZE,
PCP_KEY_TYPE_PUBLIC) != 0) {
buffer_free(blob);
goto errwa;
}
buffer_clear(blob);
}
pcphash_iteratekeysig(ptx, s) {
pcp_keysig2blob(blob, s);
if(pcpvault_additem(ptx, tmp, buffer_get(blob), buffer_size(blob),
PCP_KEYSIG_NATIVE) != 0) {
buffer_free(blob);
goto errwa;
}
buffer_clear(blob);
}
pcpvault_update_checksum(ptx, tmp);
if(pcpvault_copy(ptx, tmp, vault) == 0) {
pcpvault_unlink(tmp);
pcpvault_unlink(tmp);
}
pcpvault_free(tmp);
buffer_free(blob);
@@ -268,9 +280,9 @@ void pcpvault_update_checksum(PCPCTX *ptx, vault_t *vault) {
vault_header_t *header = ucmalloc(sizeof(vault_header_t));
header->fileid = PCP_VAULT_ID;
header->version = PCP_VAULT_VERSION;
memcpy(header->checksum, checksum, 32);
memcpy(vault->checksum, checksum, 32);
ucfree(checksum, 32);
memcpy(header->checksum, checksum, LSHA);
memcpy(vault->checksum, checksum, LSHA);
ucfree(checksum, LSHA);
vh2be(header);
@@ -292,36 +304,33 @@ byte *pcpvault_create_checksum(PCPCTX *ptx) {
size_t datasize = ((PCP_RAW_KEYSIZE) * numskeys) +
((PCP_RAW_PUBKEYSIZE) * numpkeys);
byte *data = ucmalloc(datasize);
byte *checksum = ucmalloc(32);
byte *checksum = ucmalloc(LSHA);
pcphash_iterate(ptx, k) {
key2be(k);
pcp_seckeyblob(blob, (pcp_key_t *)k);
memcpy(&data[datapos], buffer_get(blob), PCP_RAW_KEYSIZE);
memcpy(&data[datapos], buffer_get(blob), buffer_size(blob));
buffer_clear(blob);
key2native(k);
datapos += PCP_RAW_KEYSIZE;
datapos += buffer_size(blob);
}
pcp_pubkey_t *p = NULL;
pcphash_iteratepub(ptx, p) {
/* pcp_dumppubkey(p); */
pubkey2be(p);
pcp_pubkeyblob(blob, (pcp_pubkey_t *)p);
memcpy(&data[datapos], buffer_get(blob), PCP_RAW_PUBKEYSIZE);
memcpy(&data[datapos], buffer_get(blob), buffer_size(blob));
buffer_clear(blob);
pubkey2native(p);
datapos += PCP_RAW_PUBKEYSIZE;
datapos += buffer_size(blob);
}
pcp_keysig_t *s = NULL;
pcphash_iteratekeysig(ptx, s) {
pcp_keysig2blob(blob, (pcp_keysig_t *)s);
memcpy(&data[datapos], buffer_get(blob), buffer_size(blob));
buffer_clear(blob);
datapos += buffer_size(blob);
}
buffer_free(blob);
/*
printf("PUB: %d, SEC: %d\n", PCP_RAW_PUBKEYSIZE, PCP_RAW_KEYSIZE);
printf("DATA (%d) (s: %d, p: %d):\n", (int)datasize, numskeys, numpkeys);
_dump("data", data, datasize);
*/
crypto_hash_sha256(checksum, data, datasize);
memset(data, 0, datasize);
@@ -343,7 +352,7 @@ int pcpvault_copy(PCPCTX *ptx, vault_t *tmp, vault_t *vault) {
vault->fd = freopen(vault->filename, "wb+", vault->fd);
if(fwrite(in, tmpsize, 1, vault->fd) != 1) {
fatal(ptx, "Failed to copy %s to %s (write) [keeping %s]\n",
tmp->filename, vault->filename, tmp->filename);
tmp->filename, vault->filename, tmp->filename);
ucfree(in, tmpsize);
return 1;
}
@@ -351,7 +360,7 @@ int pcpvault_copy(PCPCTX *ptx, vault_t *tmp, vault_t *vault) {
if(fflush(vault->fd) != 0) {
fatal(ptx, "Failed to copy %s to %s (flush) [keeping %s]\n",
tmp->filename, vault->filename, tmp->filename);
tmp->filename, vault->filename, tmp->filename);
return 1;
}
@@ -378,7 +387,7 @@ int pcpvault_close(PCPCTX *ptx, vault_t *vault) {
if(vault != NULL) {
if(vault->fd) {
if(vault->unsafed == 1) {
pcpvault_writeall(ptx, vault);
pcpvault_writeall(ptx, vault);
}
fclose(vault->fd);
}
@@ -396,45 +405,30 @@ void pcpvault_free(vault_t *vault) {
}
vault_header_t * vh2be(vault_header_t *h) {
#ifdef __CPU_IS_BIG_ENDIAN
_32towire(h->version, (byte *)&h->version);
return h;
#else
h->version = htobe32(h->version);
return h;
#endif
}
vault_header_t * vh2native(vault_header_t *h) {
#ifdef __CPU_IS_BIG_ENDIAN
h->version = _wireto32((byte *)&h->version);
return h;
#else
h->version = be32toh(h->version);
return h;
#endif
}
vault_item_header_t * ih2be(vault_item_header_t *h) {
#ifdef __CPU_IS_BIG_ENDIAN
_32towire(h->version, (byte *)&h->version);
_32towire(h->size, (byte *)&h->size);
return h;
#else
h->version = htobe32(h->version);
h->size = htobe32(h->size);
return h;
#endif
}
vault_item_header_t * ih2native(vault_item_header_t *h) {
#ifdef __CPU_IS_BIG_ENDIAN
h->version = _wireto32((byte *)&h->version);
h->size = _wireto32((byte *)&h->size);
return h;
#else
h->version = be32toh(h->version);
h->size = be32toh(h->size);
return h;
#endif
}
int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
Buffer *raw = NULL;
size_t got = 0;
fseek(vault->fd, 0, SEEK_SET);
@@ -443,7 +437,7 @@ int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
got = fread(header, 1, sizeof(vault_header_t), vault->fd);
if(got < sizeof(vault_header_t)) {
fatal(ptx, "empty or invalid vault header size (got %ld, expected %ld)\n",
got, sizeof(vault_header_t));
got, sizeof(vault_header_t));
goto err;
}
vh2native(header);
@@ -455,66 +449,66 @@ int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
pcp_pubkey_t *pubkey;
int bytesleft = 0;
int ksize = PCP_RAW_KEYSIGSIZE; /* smallest possbile item */
raw = buffer_new(256, "rawin");
vault->version = header->version;
memcpy(vault->checksum, header->checksum, 32);
memcpy(vault->checksum, header->checksum, LSHA);
for(;;) {
readpos = ftell(vault->fd);
if(vault->size - readpos >= sizeof(vault_item_header_t)) {
/* an item header follows */
got = fread(item, sizeof(vault_item_header_t), 1, vault->fd);
ih2native(item);
/* an item header follows */
got = fread(item, sizeof(vault_item_header_t), 1, vault->fd);
ih2native(item);
if(item->size > 0) {
/* item is valid */
readpos = ftell(vault->fd);
bytesleft = vault->size - readpos;
if(bytesleft >= ksize) {
/* a key follows */
if(item->type == PCP_KEY_TYPE_MAINSECRET ||
item->type == PCP_KEY_TYPE_SECRET) {
/* read a secret key */
key = ucmalloc(sizeof(pcp_key_t));
got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd);
key2native(key);
pcphash_add(ptx, (void *)key, item->type);
}
else if(item->type == PCP_KEY_TYPE_PUBLIC) {
/* read a public key */
pubkey = ucmalloc(sizeof(pcp_pubkey_t));
got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd);
pubkey2native(pubkey);
pcphash_add(ptx, (void *)pubkey, item->type);
}
else if(item->type == PCP_KEYSIG_NATIVE || item->type == PCP_KEYSIG_PBP) {
Buffer *rawks = buffer_new(256, "keysig");
buffer_fd_read(rawks, vault->fd, item->size);
pcp_keysig_t *s = pcp_keysig_new(rawks);
pcphash_add(ptx, (void *)s, item->type);
buffer_free(rawks);
}
else {
fatal(ptx, "Failed to read vault - invalid key type: %02X! at %d\n",
item->type, readpos);
goto err;
}
}
else {
fatal(ptx, "Failed to read vault - that's no pcp key at %d (size %ld)!\n",
readpos, bytesleft);
goto err;
}
}
else {
fatal(ptx, "Failed to read vault - invalid key item header size at %d!\n",
readpos);
goto err;
}
if(item->size > 0) {
/* item is valid */
readpos = ftell(vault->fd);
bytesleft = vault->size - readpos;
if(bytesleft >= ksize) {
/* a key follows */
if(item->type == PCP_KEY_TYPE_MAINSECRET ||
item->type == PCP_KEY_TYPE_SECRET) {
/* read a secret key */
buffer_fd_read(raw, vault->fd, item->size);
key = pcp_blob2key(raw);
pcphash_add(ptx, (void *)key, item->type);
buffer_clear(raw);
}
else if(item->type == PCP_KEY_TYPE_PUBLIC) {
/* read a public key */
buffer_fd_read(raw, vault->fd, item->size);
pubkey = pcp_blob2pubkey(raw);
pcphash_add(ptx, (void *)pubkey, item->type);
buffer_clear(raw);
}
else if(item->type == PCP_KEYSIG_NATIVE || item->type == PCP_KEYSIG_PBP) {
buffer_fd_read(raw, vault->fd, item->size);
pcp_keysig_t *s = pcp_blob2keysig(raw);
pcphash_add(ptx, (void *)s, item->type);
buffer_clear(raw);
}
else {
fatal(ptx, "Failed to read vault - invalid key type: %02X! at %d\n",
item->type, readpos);
goto err;
}
}
else {
fatal(ptx, "Failed to read vault - that's no pcp key at %d (size %ld)!\n",
readpos, bytesleft);
goto err;
}
}
else {
fatal(ptx, "Failed to read vault - invalid key item header size at %d!\n",
readpos);
goto err;
}
}
else {
/* no more items */
break;
/* no more items */
break;
}
}
}
@@ -526,14 +520,9 @@ int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
byte *checksum = NULL;
checksum = pcpvault_create_checksum(ptx);
/*
_dump(" calc checksum", checksum, 32);
_dump("vault checksum", vault->checksum, 32);
*/
if(pcphash_count(ptx) + pcphash_countpub(ptx) > 0) {
/* only validate the checksum if there are keys */
if(memcmp(checksum, vault->checksum, 32) != 0) {
if(cst_time_memcmp(checksum, vault->checksum, LSHA) != 0) {
fatal(ptx, "Error: the checksum of the key vault doesn't match its contents!\n");
goto err;
}
@@ -542,11 +531,13 @@ int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
free(checksum);
free(item);
free(header);
buffer_free(raw);
return 0;
err:
free(item);
free(header);
buffer_free(raw);
/* pcphash_clean(); */
return -1;

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -35,6 +35,9 @@ static char *begins[] = {
/* via http://stackoverflow.com/a/1031773, slightly modified,
licensed under CC-BY-SA, written by Christoph
*/
uint8_t is_utf8(const byte *bytes) {
if( (// non-overlong 2-byte
(0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
@@ -51,8 +54,8 @@ uint8_t is_utf8(const byte *bytes) {
) ||
(// straight 3-byte
((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
bytes[0] == 0xEE ||
bytes[0] == 0xEF) &&
bytes[0] == 0xEE ||
bytes[0] == 0xEF) &&
(0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
) ||
@@ -104,25 +107,25 @@ size_t _buffer_is_binary(byte *buf, size_t len) {
/* check for utf8 */
wide[0] = buf[pos];
for(i=1; i<3; i++) {
/* check for 2, 3 or 4 byte utf8 char */
if(pos+i < len) {
/* only if there's enough space of course */
wide[i] = buf[pos+i];
if(is_utf8(wide) > 1) {
pos += i; /* jump over the utf we already found */
utf = 1;
break;
}
}
else
break;
/* check for 2, 3 or 4 byte utf8 char */
if(pos+i < len) {
/* only if there's enough space of course */
wide[i] = buf[pos+i];
if(is_utf8(wide) > 1) {
pos += i; /* jump over the utf we already found */
utf = 1;
break;
}
}
else
break;
}
memset(wide, 0, 4);
if(utf == 1) {
/* it's a utf8 char, continue checking, reset wide */
utf = 0;
continue;
/* it's a utf8 char, continue checking, reset wide */
utf = 0;
continue;
}
break; /* if we reach this, then it's binary and not utf8, stop checking */
}
@@ -173,7 +176,6 @@ byte *pcp_z85_decode(PCPCTX *ptx, char *z85block, size_t *dstlen) {
byte padblob[4];
srclen = strlen(z85block);
if(srclen == 0) {
/* FIXME: check how this happens, pcpstream decoder call */
*dstlen = 0;
@@ -212,7 +214,7 @@ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen, int doblock) {
char *padblob = NULL;
char *z85 = NULL;
char *z85block = NULL;
if(srclen %4 == 0) {
/* no padding required */
padded = raw;
@@ -229,6 +231,9 @@ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen, int doblock) {
zlen = (outlen * 5 / 4) + 1;
z85 = ucmalloc(zlen + 5); /* plus space for pad blob */
z85 = zmq_z85_encode(z85, padded, outlen);
if (z85 == NULL) {
perror("zmq_z85_encode *z85 failed!");
}
if(srclen %4 != 0)
free(padded);
@@ -237,7 +242,9 @@ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen, int doblock) {
padblob = ucmalloc(6);
rpad = urmalloc(4);
rpad[3] = (int)padlen;
zmq_z85_encode(padblob, rpad, 4);
if(zmq_z85_encode(padblob, rpad, 4) == NULL) {
perror("zmq_z85_encode *padblob failed!");
}
/* append pad blob to encoded output */
memcpy(&z85[zlen-1], padblob, 5);
@@ -254,12 +261,12 @@ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen, int doblock) {
while(*z != '\0') {
if(pos >= 71) {
*B++ = '\r';
*B++ = '\n';
pos = 1;
*B++ = '\r';
*B++ = '\n';
pos = 1;
}
else {
pos++;
pos++;
}
*B++ = *z++;
}
@@ -329,27 +336,27 @@ char *pcp_readz85string(PCPCTX *ptx, unsigned char *input, size_t bufsize) {
else if(input[i] == '\n') {
/* a line is complete */
if(z85_isbegin(line) && begin == 0) {
/* a begin header, reset whatever we've got so far in z buffer */
begin = 1;
buffer_clear(line);
buffer_clear(z);
continue;
/* a begin header, reset whatever we've got so far in z buffer */
begin = 1;
buffer_clear(line);
buffer_clear(z);
continue;
}
else if(z85_isend(line)){
/* an end header */
buffer_clear(line);
end = 1;
break;
/* an end header */
buffer_clear(line);
end = 1;
break;
}
else if(z85_isempty(line) || z85_iscomment(line)) {
/* a comment */
buffer_clear(line);
continue;
/* a comment */
buffer_clear(line);
continue;
}
else {
/* regular z85 encoded content */
buffer_add_buf(z, line);
buffer_clear(line);
/* regular z85 encoded content */
buffer_add_buf(z, line);
buffer_clear(line);
}
}
else {
@@ -467,7 +474,7 @@ int z85_isbegin(Buffer *buf) {
blen = strlen(begin);
if(blen <= len)
if(_findoffset(line+buf->offset, len, (char *)begin, blen) >= 0)
isb = i; /* i = ENUM ZBEGINS */
isb = i; /* i = ENUM ZBEGINS */
}
free(line);

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
@@ -28,21 +28,22 @@ static char encoder [85 + 1] = {
"}@%$#"
};
/* Maps base 85 to base 256 */
/* We chop off lower 32 and higher 128 ranges */
/* Maps base 85 to base 256
We chop off lower 32 and higher 128 ranges
0xFF denotes invalid characters within this range */
static uint8_t decoder [96] = {
0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00,
0x4B, 0x4C, 0x46, 0x41, 0x00, 0x3F, 0x3E, 0x45,
0xFF, 0x44, 0xFF, 0x54, 0x53, 0x52, 0x48, 0xFF,
0x4B, 0x4C, 0x46, 0x41, 0xFF, 0x3F, 0x3E, 0x45,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x40, 0x00, 0x49, 0x42, 0x4A, 0x47,
0x08, 0x09, 0x40, 0xFF, 0x49, 0x42, 0x4A, 0x47,
0x51, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
0x3B, 0x3C, 0x3D, 0x4D, 0x00, 0x4E, 0x43, 0x00,
0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
0x3B, 0x3C, 0x3D, 0x4D, 0xFF, 0x4E, 0x43, 0xFF,
0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
0x21, 0x22, 0x23, 0x4F, 0x00, 0x50, 0x00, 0x00
0x21, 0x22, 0x23, 0x4F, 0xFF, 0x50, 0xFF, 0xFF
};
/* -------------------------------------------------------------------------- */
@@ -50,19 +51,26 @@ static uint8_t decoder [96] = {
/* size * 5 / 4 bytes long plus 1 byte for the null terminator. Returns */
/* dest. Size must be a multiple of 4. */
char *zmq_z85_encode (char *dest, uint8_t *data, size_t size)
{
if (size % 4 != 0)
return NULL; /* !assert */
/* --------------------------------------------------------------------------
Encode a binary frame as a string; destination string MUST be at least
size * 5 / 4 bytes long plus 1 byte for the null terminator. Returns
dest. Size must be a multiple of 4.
Returns NULL and sets errno = EINVAL for invalid input. */
char *zmq_z85_encode (char *dest, const uint8_t *data, size_t size)
{
if (size % 4 != 0) {
errno = EINVAL;
return NULL;
}
unsigned int char_nbr = 0;
unsigned int byte_nbr = 0;
uint32_t value = 0;
while (byte_nbr < size) {
/* Accumulate value in base 256 (binary) */
// Accumulate value in base 256 (binary)
value = value * 256 + data [byte_nbr++];
if (byte_nbr % 4 == 0) {
/* Output value in base 85 */
// Output value in base 85
unsigned int divisor = 85 * 85 * 85 * 85;
while (divisor) {
dest [char_nbr++] = encoder [value / divisor % 85];
@@ -71,32 +79,44 @@ char *zmq_z85_encode (char *dest, uint8_t *data, size_t size)
value = 0;
}
}
if (char_nbr != size * 5 / 4)
return NULL; /* !assert */
if (char_nbr != size * 5 / 4) {
return NULL; /* !assert */
}
dest [char_nbr] = 0;
return dest;
}
/* -------------------------------------------------------------------------- */
/* Decode an encoded string into a binary frame; dest must be at least */
/* strlen (string) * 4 / 5 bytes long. Returns dest. strlen (string) */
/* must be a multiple of 5. */
// --------------------------------------------------------------------------
// Decode an encoded string into a binary frame; dest must be at least
// strlen (string) * 4 / 5 bytes long. Returns dest. strlen (string)
// must be a multiple of 5.
// Returns NULL and sets errno = EINVAL for invalid input.
uint8_t *zmq_z85_decode (uint8_t *dest, char *string)
uint8_t *zmq_z85_decode (uint8_t *dest, const char *string)
{
if (strlen (string) % 5 != 0)
return NULL; /* !assert */
unsigned int byte_nbr = 0;
unsigned int char_nbr = 0;
uint32_t value = 0;
size_t string_len = strlen (string);
while (char_nbr < string_len) {
/* Accumulate value in base 85 */
value = value * 85 + decoder [(uint8_t) string [char_nbr++] - 32];
while (string[char_nbr]) {
// Accumulate value in base 85
if (UINT32_MAX / 85 < value) {
// Invalid z85 encoding, represented value exceeds 0xffffffff
goto error_inval;
}
value *= 85;
uint8_t index = string [char_nbr++] - 32;
if (index >= sizeof(decoder)) {
// Invalid z85 encoding, character outside range
goto error_inval;
}
uint32_t summand = decoder [index];
if (summand == 0xFF || summand > (UINT32_MAX - value)) {
// Invalid z85 encoding, invalid character or represented value exceeds 0xffffffff
goto error_inval;
}
value += summand;
if (char_nbr % 5 == 0) {
/* Output value in base 256 */
// Output value in base 256
unsigned int divisor = 256 * 256 * 256;
while (divisor) {
dest [byte_nbr++] = value / divisor % 256;
@@ -105,7 +125,15 @@ uint8_t *zmq_z85_decode (uint8_t *dest, char *string)
value = 0;
}
}
if (byte_nbr != strlen (string) * 4 / 5)
return NULL; /* !assert */
if (char_nbr % 5 != 0) {
goto error_inval;
}
if (byte_nbr != strlen (string) * 4 / 5) {
goto error_inval;
}
return dest;
error_inval:
errno = EINVAL;
return NULL;
}

View File

@@ -286,6 +286,26 @@ B<In short: don NOT use this software for production purposes!>
=head1 INTERNALS
=head2 PASSPHRASES
Passphrases are used to protect secret data at rest on various instances
by pcp, like secret keys or symmetric encrypted data.
Pcp doesn't use the passphrase directly but uses a key derivation function
to calculate a secure key from the passphrase: libsodium's
B<crypto_pwhash_scryptsalsa208sha256()> function.
In order to properly protect secret keys, pcp measures the entropy
of a given passphrase and warns the user about the possible weak
passphrase. This measurement is calculated using the Claude E. Shannon
method, where a value of 8.0 means maximum available entropy (e.g.
truly random 256 chars in no comprehensible order) and 0.0 stands
for the worst like passphrases like "aaa" or "x".
Pcp considers passphrases with an entropy measurement of 3.32 or higher
as acceptable. This may change in the future.
=head2 VAULT FORMAT
The vault file contains all public and secret keys. It's a portable

View File

@@ -1,3 +1,4 @@
=head1 INSTALLATION
There are currently no packages available, so B<pcp> has to be
@@ -13,7 +14,20 @@ First, you will need libsodium:
sudo ldconfig
cd ..
Next, pcp:
If you want to have JSON support, you'll need to install the
Jansson library (optional):
git clone git://github.com/akheron/jansson.git
cd jansson
autoreconf -i
./configure && make
sudo make install
cd ..
In order to use the python binding, you need to install the
B<cffi> python package.
Next, build pcp:
git clone git://github.com/tlinden/pcp.git
cd pcp

View File

@@ -1,3 +1,4 @@
=head1 OPTIONS
Usage: pcp1 [options]
@@ -9,10 +10,13 @@
will be used.
-I --infile <file> Input file. If not specified, stdin
will be used.
-x --xpass <passwd> Provide password. B<INSECURE>! Use for
testing or debugging only!
-X --password-file <file> Read passphrase from <file>. If <file>
is -, read from stdin. This takes
precedence over other uses of stdin
elsewhere, see below for more details.
--extpass <program> Use external program for password prompt.
-i --keyid <id> Specify a key id to import/export.
-r --recipient <string> Specify a recpipient, used for public
key export and encryption.
@@ -26,7 +30,7 @@
--version Print program version.
-D --debug Enable debug output.
-v --verbose Enable verbose output.
Keymanagement Options:
-k --keygen Generate a CURVE25519 secret key. If
the generated key is the first one in
@@ -35,9 +39,7 @@
been specified, don't store the generated
key to the vault but export it to the
file instead. You will be asked for
an owner, mail and a passphrase. If you
leave the passphrase empty, the key will
be stored unencrypted.
an owner, mail and a passphrase.
-l --listkeys List all keys currently stored in your
vault. Only the key id's and some info
about the keys will be printed, not the
@@ -132,11 +134,9 @@
uses stdin/stdout
Misc Options:
-C --checksum [<key>] Calculate a Blake2b checksum of one or more files.
If <key> is provided, an authenticated hash will
be calculated, otherwise a normal hash. If you don't
want to generate an authenticated hash, specify
-- after -C.
-C --checksum Calculate a Blake2b checksum of one or more files.
If -x is provided, an authenticated hash will
be calculated, otherwise a normal hash.
Use -I to specify one file or put multiple file
names after -C like "pcp1 -C -- file1 file2 file3".

View File

@@ -1,4 +1,4 @@
.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -38,8 +38,6 @@
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
@@ -50,24 +48,17 @@
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
.ie \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
.el \{\
. de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{
. if \nF \{
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -133,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PCP1 1"
.TH PCP1 1 "2015-07-21" "PCP 0.3.0" "USER CONTRIBUTED DOCUMENTATION"
.TH PCP1 1 "2016-10-26" "PCP 0.4.0" "USER CONTRIBUTED DOCUMENTATION"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -158,7 +149,10 @@ Pretty Curved Privacy \- File encryption using eliptic curve cryptography.
\& \-V \-\-vault <vaultfile> Specify an alternate vault file.
\& \-O \-\-outfile <file> Output file. STDOUT if unspecified.
\& \-I \-\-infile <file> Input file. STDIN if unspecified.
\& \-x \-\-xpass <passwd> Provide password. INSECURE! Use for testing
\& or debugging only!
\& \-X \-\-password\-file <file> Read passphrase from <file>.
\& \-\-extpass <program> Use external program for password prompt.
\& \-i \-\-keyid <id> Specify a key id for various operations.
\& \-r \-\-recipient <string> Specify a recpipient, multiple allowed.
\& \-t \-\-text Print textual representation of ojects.
@@ -193,13 +187,16 @@ Pretty Curved Privacy \- File encryption using eliptic curve cryptography.
\& \-a \-\-armor \-\-textmode same as \-z
\&
\& Misc Options:
\& \-C \-\-checksum [<key>] calculate a Blake2 checksum of one or more files.
\& \-C \-\-checksum calculate a Blake2 checksum of one or more files.
\& add \-x <key> to compute an authenticated hash.
\&
\& Arguments:
\& Extra arguments after options are treated as filenames or
\& recipients, depending on operation mode.
\&=head1 OPTIONS
\&
.Ve
.SH "OPTIONS"
.IX Header "OPTIONS"
.Vb 1
\& Usage: pcp1 [options]
\&
\& General Options:
@@ -209,10 +206,13 @@ Pretty Curved Privacy \- File encryption using eliptic curve cryptography.
\& will be used.
\& \-I \-\-infile <file> Input file. If not specified, stdin
\& will be used.
\& \-x \-\-xpass <passwd> Provide password. B<INSECURE>! Use for
\& testing or debugging only!
\& \-X \-\-password\-file <file> Read passphrase from <file>. If <file>
\& is \-, read from stdin. This takes
\& precedence over other uses of stdin
\& elsewhere, see below for more details.
\& \-\-extpass <program> Use external program for password prompt.
\& \-i \-\-keyid <id> Specify a key id to import/export.
\& \-r \-\-recipient <string> Specify a recpipient, used for public
\& key export and encryption.
@@ -226,7 +226,7 @@ Pretty Curved Privacy \- File encryption using eliptic curve cryptography.
\& \-\-version Print program version.
\& \-D \-\-debug Enable debug output.
\& \-v \-\-verbose Enable verbose output.
\&
\&
\& Keymanagement Options:
\& \-k \-\-keygen Generate a CURVE25519 secret key. If
\& the generated key is the first one in
@@ -235,9 +235,7 @@ Pretty Curved Privacy \- File encryption using eliptic curve cryptography.
\& been specified, don\*(Aqt store the generated
\& key to the vault but export it to the
\& file instead. You will be asked for
\& an owner, mail and a passphrase. If you
\& leave the passphrase empty, the key will
\& be stored unencrypted.
\& an owner, mail and a passphrase.
\& \-l \-\-listkeys List all keys currently stored in your
\& vault. Only the key id\*(Aqs and some info
\& about the keys will be printed, not the
@@ -332,11 +330,9 @@ Pretty Curved Privacy \- File encryption using eliptic curve cryptography.
\& uses stdin/stdout
\&
\& Misc Options:
\& \-C \-\-checksum [<key>] Calculate a Blake2b checksum of one or more files.
\& If <key> is provided, an authenticated hash will
\& be calculated, otherwise a normal hash. If you don\*(Aqt
\& want to generate an authenticated hash, specify
\& \-\- after \-C.
\& \-C \-\-checksum Calculate a Blake2b checksum of one or more files.
\& If \-x is provided, an authenticated hash will
\& be calculated, otherwise a normal hash.
\& Use \-I to specify one file or put multiple file
\& names after \-C like "pcp1 \-C \-\- file1 file2 file3".
.Ve
@@ -346,7 +342,7 @@ Pretty Curved Privacy \- File encryption using eliptic curve cryptography.
be used to encrypt files. \fBpcp1\fR uses eliptc curve cryptography
for encryption (\s-1CURVE25519\s0 by Dan J. Bernstein). While \s-1CURVE25519\s0
is no worldwide accepted standard it hasn't been compromised by
the \s-1NSA \-\s0 which might be better, depending on your point of view.
the \s-1NSA\s0 \- which might be better, depending on your point of view.
.PP
\&\fBCaution\fR: since \s-1CURVE25519\s0 is no accepted standard, \fBpcp1\fR has
to be considered as experimental software. In fact, I wrote it just
@@ -672,10 +668,10 @@ Enable debugging output, where supported. Same as \fB\-D\fR.
.IX Header "EXIT STATUS"
Pcp may return one of several error codes if it encounters problems.
.IP "0 No problems occurred." 4
.IX Item "0 No problems occurred."
.IX Item "0 No problems occurred."
.PD 0
.IP "1 Generic error code." 4
.IX Item "1 Generic error code."
.IX Item "1 Generic error code."
.PD
.SH "FILES"
.IX Header "FILES"
@@ -724,7 +720,25 @@ don't use it for anything remotely serious.
\&\fBIn short: don \s-1NOT\s0 use this software for production purposes!\fR
.SH "INTERNALS"
.IX Header "INTERNALS"
.SS "\s-1VAULT FORMAT\s0"
.SS "\s-1PASSPHRASES\s0"
.IX Subsection "PASSPHRASES"
Passphrases are used to protect secret data at rest on various instances
by pcp, like secret keys or symmetric encrypted data.
.PP
Pcp doesn't use the passphrase directly but uses a key derivation function
to calculate a secure key from the passphrase: libsodium's
\&\fB\f(BIcrypto_pwhash_scryptsalsa208sha256()\fB\fR function.
.PP
In order to properly protect secret keys, pcp measures the entropy
of a given passphrase and warns the user about the possible weak
passphrase. This measurement is calculated using the Claude E. Shannon
method, where a value of 8.0 means maximum available entropy (e.g.
truly random 256 chars in no comprehensible order) and 0.0 stands
for the worst like passphrases like \*(L"aaa\*(R" or \*(L"x\*(R".
.PP
Pcp considers passphrases with an entropy measurement of 3.32 or higher
as acceptable. This may change in the future.
.SS "\s-1VAULT\s0 \s-1FORMAT\s0"
.IX Subsection "VAULT FORMAT"
The vault file contains all public and secret keys. It's a portable
binary file.
@@ -771,7 +785,7 @@ Type can be one of:
.Ve
.PP
The key header is followed by the actual key, see below.
.SS "\s-1SECRET KEY FORMAT\s0"
.SS "\s-1SECRET\s0 \s-1KEY\s0 \s-1FORMAT\s0"
.IX Subsection "SECRET KEY FORMAT"
A secret key is a binary structure with the following format:
.PP
@@ -840,7 +854,7 @@ are otherwise unrelated. If one of them leaks, the other
cannot be recalculated from it.
.PP
Take a look at the function \fB\f(BIpcp_keypairs()\fB\fR for details.
.SS "\s-1PUBLIC KEY EXPORT FORMAT\s0"
.SS "\s-1PUBLIC\s0 \s-1KEY\s0 \s-1EXPORT\s0 \s-1FORMAT\s0"
.IX Subsection "PUBLIC KEY EXPORT FORMAT"
Exported public and secret keys will be written in a portable
way. Pcp uses \s-1RFC4880\s0 export format for public keys with some
@@ -944,7 +958,7 @@ So, a full pubkey export looks like this
\& hash
\& signature
.Ve
.SS "\s-1SECRET KEY EXPORT FORMAT\s0"
.SS "\s-1SECRET\s0 \s-1KEY\s0 \s-1EXPORT\s0 \s-1FORMAT\s0"
.IX Subsection "SECRET KEY EXPORT FORMAT"
Secret keys are exported in a proprietary format.
.PP
@@ -976,7 +990,7 @@ to encrypt the data and looks after encryption as such:
.Vb 1
\& Nonce | Cipher
.Ve
.SS "\s-1ENCRYPTED OUTPUT FORMAT\s0"
.SS "\s-1ENCRYPTED\s0 \s-1OUTPUT\s0 \s-1FORMAT\s0"
.IX Subsection "ENCRYPTED OUTPUT FORMAT"
The encryption protocol used by \s-1PCP\s0 uses mostly standard
libsodium facilities with the exception that \s-1PCP\s0 uses counter
@@ -1069,7 +1083,7 @@ of the sender.
The encrypted output maybe Z85 encoded. In this case the Z85
encoding will be done blockwise with blocks of 16k bytes. The
decoded content inside will be as described above.
.SS "\s-1SIGNATURE FORMAT\s0"
.SS "\s-1SIGNATURE\s0 \s-1FORMAT\s0"
.IX Subsection "SIGNATURE FORMAT"
There are different signature formats. Standard binary \s-1NACL\s0
signatures have the following format:
@@ -1121,15 +1135,15 @@ Armored signatures have the following format:
.PP
The Z85 encoded signature at the end contains the same signature
contents as the binary signature outlined above (hash+sig).
.SS "\s-1SIGNED ENCRYPTION FORMAT\s0"
.SS "\s-1SIGNED\s0 \s-1ENCRYPTION\s0 \s-1FORMAT\s0"
.IX Subsection "SIGNED ENCRYPTION FORMAT"
Signed encrypted files are in binary form only. The first part is
the standard encrypted file as described in \fB\s-1ENCRYPTED OUTPUT FORMAT\s0\fR
followed by the binary encrypted signature described in \fB\s-1SIGNATURE FORMAT\s0\fR
the standard encrypted file as described in \fB\s-1ENCRYPTED\s0 \s-1OUTPUT\s0 \s-1FORMAT\s0\fR
followed by the binary encrypted signature described in \fB\s-1SIGNATURE\s0 \s-1FORMAT\s0\fR
without the offset separator.
.PP
However, not only the hash of the file content will be signed but the
recipient list described in \fB\s-1ENCRYPTED OUTPUT FORMAT\s0\fR as well. A
recipient list described in \fB\s-1ENCRYPTED\s0 \s-1OUTPUT\s0 \s-1FORMAT\s0\fR as well. A
valid recipient is therefore not able to re-encrypt the decrypted
message, append the original signature and send it to other recipients.
The signature would not match since the recipient list differs and
@@ -1169,7 +1183,7 @@ Before encryption the signature format is:
\& +\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
.Ve
.PP
where R is: C(recipient)|C(recipient)... (see \fB\s-1ENCRYPTED OUTPUT FORMAT\s0\fR).
where R is: C(recipient)|C(recipient)... (see \fB\s-1ENCRYPTED\s0 \s-1OUTPUT\s0 \s-1FORMAT\s0\fR).
.PP
Pseudocode:
.PP
@@ -1236,9 +1250,9 @@ pcp1 \-z \-I file \-O file.z85
Reverse the process:
.PP
pcp1 \-Z \-I file.z85 \-O file
.SS "\s-1PBP COMPATIBILITY\s0"
.SS "\s-1PBP\s0 \s-1COMPATIBILITY\s0"
.IX Subsection "PBP COMPATIBILITY"
\&\s-1PCP\s0 tries to be fully compatible with \s-1PBP \s0(https://github.com/stef/pbp). Encrypted
\&\s-1PCP\s0 tries to be fully compatible with \s-1PBP\s0 (https://github.com/stef/pbp). Encrypted
files and signatures \- at least their binary versions \- should be exchangable. However,
this is a work in progress and might not work under all circumstances. Also there's currently
no shared key format between pbp and pcp. However, it is possible to export and
@@ -1262,8 +1276,8 @@ functions:
.PD
.PP
\&\s-1JSON\s0 support can be used either with the commandline tool \fBpcp1\fR or programmatically
using the C, \*(C+ or Python \s-1API.\s0
.SS "\s-1USING JSON FROM THE C API\s0"
using the C, \*(C+ or Python \s-1API\s0.
.SS "\s-1USING\s0 \s-1JSON\s0 \s-1FROM\s0 \s-1THE\s0 C \s-1API\s0"
.IX Subsection "USING JSON FROM THE C API"
In order to use \s-1JSON\s0 all you've got to do is to switch a context flag:
.PP
@@ -1273,9 +1287,9 @@ In order to use \s-1JSON\s0 all you've got to do is to switch a context flag:
.Ve
.PP
That all to it. Now any function normally used for key import and export works
with \s-1JSON,\s0 just fill the \fBBuffer\fR object with a \s-1JSON\s0 string for imports or
with \s-1JSON\s0, just fill the \fBBuffer\fR object with a \s-1JSON\s0 string for imports or
fetch the Buffer content of an export function as a string.
.SS "\s-1USING JSON FROM THE COMMANDLINE\s0"
.SS "\s-1USING\s0 \s-1JSON\s0 \s-1FROM\s0 \s-1THE\s0 \s-1COMMANDLINE\s0"
.IX Subsection "USING JSON FROM THE COMMANDLINE"
In order to use \s-1JSON\s0 on the commandline, add \fB\-j\fR. This can be used in
conjunction with the following options:
@@ -1293,9 +1307,9 @@ Public and secret key import.
Text view mode (aka inspect mode).
.PP
The \fB\-z\fR and \fB\-Z\fR options are ignored in \s-1JSON\s0 mode.
.SS "\s-1JSON OBJECT STRUCTURE\s0"
.SS "\s-1JSON\s0 \s-1OBJECT\s0 \s-1STRUCTURE\s0"
.IX Subsection "JSON OBJECT STRUCTURE"
\fI\s-1JSON PUBLIC KEY \s0(pcp1 \-p \-j)\fR
\fI\s-1JSON\s0 \s-1PUBLIC\s0 \s-1KEY\s0 (pcp1 \-p \-j)\fR
.IX Subsection "JSON PUBLIC KEY (pcp1 -p -j)"
.PP
The \s-1JSON\s0 object for a public key looks like this:
@@ -1324,7 +1338,7 @@ Fields containing byte arrays are hex encoded.
.PP
Numbers are represented as literal integers.
.PP
\fI\s-1JSON SECRET KEY \s0(pcp1 \-s \-j)\fR
\fI\s-1JSON\s0 \s-1SECRET\s0 \s-1KEY\s0 (pcp1 \-s \-j)\fR
.IX Subsection "JSON SECRET KEY (pcp1 -s -j)"
.PP
The \s-1JSON\s0 object for a public key looks like this:
@@ -1355,7 +1369,7 @@ secret key material. Pcp does not support exporting a secret key unencrypted.
The \fBnonce\fR is required for a later import and shall not be changed or
decoupled from \fBsecrets\fR. This may change in the future.
.PP
\fI\s-1JSON VAULT \s0(pcp1 \-t)\fR
\fI\s-1JSON\s0 \s-1VAULT\s0 (pcp1 \-t)\fR
.IX Subsection "JSON VAULT (pcp1 -t)"
.PP
The \s-1JSON\s0 object for the vault looks like this:
@@ -1374,7 +1388,7 @@ The \s-1JSON\s0 object for the vault looks like this:
The field \fBkeys\fR is an array containing one or more of the already
described key objects.
.PP
\fI\s-1JSON PROGRAM OUTPUT\s0\fR
\fI\s-1JSON\s0 \s-1PROGRAM\s0 \s-1OUTPUT\s0\fR
.IX Subsection "JSON PROGRAM OUTPUT"
.PP
Currently pcp does not support \s-1JSON\s0 program output, that is, success or
@@ -1423,7 +1437,7 @@ under the \fB\s-1GPL\s0\fR as well.
\&\fIT.v.Dein <tom \s-1AT\s0 vondein \s-1DOT\s0 org\fR>
.SH "LICENSE"
.IX Header "LICENSE"
Licensed under the \s-1GNU GENERAL PUBLIC LICENSE\s0 version 3.
Licensed under the \s-1GNU\s0 \s-1GENERAL\s0 \s-1PUBLIC\s0 \s-1LICENSE\s0 version 3.
.SH "HOME"
.IX Header "HOME"
The homepage of Pretty Curved Privacy can be found on

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,10 @@ Pretty Curved Privacy - File encryption using eliptic curve cryptography.
-V --vault <vaultfile> Specify an alternate vault file.
-O --outfile <file> Output file. STDOUT if unspecified.
-I --infile <file> Input file. STDIN if unspecified.
-x --xpass <passwd> Provide password. INSECURE! Use for testing
or debugging only!
-X --password-file <file> Read passphrase from <file>.
--extpass <program> Use external program for password prompt.
-i --keyid <id> Specify a key id for various operations.
-r --recipient <string> Specify a recpipient, multiple allowed.
-t --text Print textual representation of ojects.
@@ -56,11 +59,13 @@ Pretty Curved Privacy - File encryption using eliptic curve cryptography.
-a --armor --textmode same as -z
Misc Options:
-C --checksum [<key>] calculate a Blake2 checksum of one or more files.
-C --checksum calculate a Blake2 checksum of one or more files.
add -x <key> to compute an authenticated hash.
Arguments:
Extra arguments after options are treated as filenames or
recipients, depending on operation mode.
=head1 OPTIONS
Usage: pcp1 [options]
@@ -72,10 +77,13 @@ Pretty Curved Privacy - File encryption using eliptic curve cryptography.
will be used.
-I --infile <file> Input file. If not specified, stdin
will be used.
-x --xpass <passwd> Provide password. B<INSECURE>! Use for
testing or debugging only!
-X --password-file <file> Read passphrase from <file>. If <file>
is -, read from stdin. This takes
precedence over other uses of stdin
elsewhere, see below for more details.
--extpass <program> Use external program for password prompt.
-i --keyid <id> Specify a key id to import/export.
-r --recipient <string> Specify a recpipient, used for public
key export and encryption.
@@ -89,7 +97,7 @@ Pretty Curved Privacy - File encryption using eliptic curve cryptography.
--version Print program version.
-D --debug Enable debug output.
-v --verbose Enable verbose output.
Keymanagement Options:
-k --keygen Generate a CURVE25519 secret key. If
the generated key is the first one in
@@ -98,9 +106,7 @@ Pretty Curved Privacy - File encryption using eliptic curve cryptography.
been specified, don't store the generated
key to the vault but export it to the
file instead. You will be asked for
an owner, mail and a passphrase. If you
leave the passphrase empty, the key will
be stored unencrypted.
an owner, mail and a passphrase.
-l --listkeys List all keys currently stored in your
vault. Only the key id's and some info
about the keys will be printed, not the
@@ -195,11 +201,9 @@ Pretty Curved Privacy - File encryption using eliptic curve cryptography.
uses stdin/stdout
Misc Options:
-C --checksum [<key>] Calculate a Blake2b checksum of one or more files.
If <key> is provided, an authenticated hash will
be calculated, otherwise a normal hash. If you don't
want to generate an authenticated hash, specify
-- after -C.
-C --checksum Calculate a Blake2b checksum of one or more files.
If -x is provided, an authenticated hash will
be calculated, otherwise a normal hash.
Use -I to specify one file or put multiple file
names after -C like "pcp1 -C -- file1 file2 file3".
@@ -596,6 +600,26 @@ B<In short: don NOT use this software for production purposes!>
=head1 INTERNALS
=head2 PASSPHRASES
Passphrases are used to protect secret data at rest on various instances
by pcp, like secret keys or symmetric encrypted data.
Pcp doesn't use the passphrase directly but uses a key derivation function
to calculate a secure key from the passphrase: libsodium's
B<crypto_pwhash_scryptsalsa208sha256()> function.
In order to properly protect secret keys, pcp measures the entropy
of a given passphrase and warns the user about the possible weak
passphrase. This measurement is calculated using the Claude E. Shannon
method, where a value of 8.0 means maximum available entropy (e.g.
truly random 256 chars in no comprehensible order) and 0.0 stands
for the worst like passphrases like "aaa" or "x".
Pcp considers passphrases with an entropy measurement of 3.32 or higher
as acceptable. This may change in the future.
=head2 VAULT FORMAT
The vault file contains all public and secret keys. It's a portable

120
meson.build Normal file
View File

@@ -0,0 +1,120 @@
# -*-python-*-
project(
'pcp',
'c',
license: 'GPL',
version: '0.4.1',
meson_version: '>=1.3',
default_options: [
'warning_level=2',
'werror=true',
],
)
add_project_arguments(
[
'-Wno-unused-parameter',
'-Wno-unused-result',
'-Wno-missing-braces',
'-Wno-format-zero-length',
'-Wno-implicit-fallthrough',
#'-Wvla',
'-Wno-sign-compare',
'-Wno-narrowing'
],
language: 'c',
)
c = meson.get_compiler('c')
conf = configuration_data()
pcp_inc = include_directories('src', 'libpcp')
if host_machine.system().startswith('freebsd')
pcp_inc = include_directories('.', '/usr/local/include')
add_project_link_arguments('LDFLAGS=/usr/local/lib')
endif
# check for funcs.
foreach func : ['getopt', 'fdopen', 'fgetc', 'getenv', 'getpass', 'arc4random', 'fopen', 'fread', 'fwrite', 'ftruncate', 'fprintf', 'isatty', 'malloc', 'memset', 'memcpy', 'perror', 'posix_memalign', 'setrlimit', 'strnlen', 'strlen', 'strtol', 'tcgetattr', 'umask', 'towlower', 'getopt', 'getopt_long', 'vasprintf',]
conf.set('HAVE_'+func.to_upper(),
c.has_function(
func,
prefix : '#include <unistd.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/resource.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <termios.h>\n#include <wctype.h>\n#include <getopt.h>',
)
)
endforeach
if host_machine.system().startswith('freebsd')
conf.set('HAVE_STRNSTR',
c.has_function(
'strnstr',
prefix: '#include <string.h>'
))
else
bsd = c.find_library('bsd')
conf.set('HAVE_STRNSTR',
c.has_function(
'strnstr',
prefix: '#include <bsd/string.h>',
dependencies: bsd,
))
add_project_dependencies(bsd, language: 'c')
endif
# check commandline options
prefix = get_option('prefix')
if get_option('buildtype') == 'debug'
conf.set('DEBUG', '1')
endif
# setup conf map
version = '@0@'.format(meson.project_version())
conf.set('prefix', prefix)
conf.set('VERSION', version)
subdir('libpcp')
# code
pcp_sources = files(
'src/compat_getopt.c',
'src/encryption.c',
'src/keymgmt.c',
'src/keyprint.c',
'src/pcp.c',
'src/signature.c',
'src/z85util.c'
)
executable(
'pcp',
[pcp_sources],
include_directories: [pcp_inc],
dependencies: [libpcp_dep, jansson],
install: true
)
# build manual page
pod2man = find_program('pod2man', native: true)
if pod2man.found()
res = run_command(pod2man.full_path(), 'man/pcp.pod', 'pcp.1', check:true)
if res.returncode() == 0
install_man('pcp.1')
endif
endif
subdir('tests')

1
meson_options.txt Normal file
View File

@@ -0,0 +1 @@
# custom build options

View File

@@ -20,14 +20,14 @@
#
AM_CFLAGS = -I../include/pcp -I../libpcp/scrypt/crypto
AM_CFLAGS = -I../include/pcp
EXTRA_DIST = *.h
bin_PROGRAMS = pcp1
pcp1_LDADD = ../libpcp/.libs/libpcp1.a
pcp1_SOURCES = pcp.c keymgmt.c keyprint.c readpass.c \
pcp1_SOURCES = pcp.c keymgmt.c keyprint.c \
encryption.c z85util.c signature.c \
compat_getopt.c

View File

@@ -26,11 +26,9 @@
#ifndef MY_GETOPT_H_INCLUDED
#define MY_GETOPT_H_INCLUDED
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if defined(HAVE_GETOPT_H) && defined(HAVE_GETOPT_LONG)
#if defined(HAVE_GETOPT) && defined(HAVE_GETOPT_LONG)
#include <getopt.h>
#else
@@ -51,7 +49,7 @@ extern "C" {
#define optarg my_optarg
/* UNIX-style short-argument parser */
extern int my_getopt(int argc, char * argv[], const char *opts);
extern int my_getopt(int argc, char *argv[], const char *opts);
extern int my_optind, my_opterr, my_optopt;
extern char *my_optarg;
@@ -72,15 +70,15 @@ struct option {
#define optional_argument 2
/* GNU-style long-argument parsers */
extern int my_getopt_long(int argc, char * argv[], const char *shortopts,
const struct option *longopts, int *longind);
extern int my_getopt_long(int argc, char *argv[], const char *shortopts,
const struct option *longopts, int *longind);
extern int my_getopt_long_only(int argc, char * argv[], const char *shortopts,
const struct option *longopts, int *longind);
extern int my_getopt_long_only(int argc, char *argv[], const char *shortopts,
const struct option *longopts, int *longind);
extern int _my_getopt_internal(int argc, char * argv[], const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
extern int _my_getopt_internal(int argc, char *argv[], const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#ifdef __cplusplus
}

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2015 T.v.Dein.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -66,57 +66,61 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
char *passphrase;
if(passwd == NULL) {
pcp_readpass(&passphrase,
"Enter passphrase for symetric decryption", NULL, 1, NULL);
pcp_readpass(ptx, &passphrase,
"Enter passphrase for symetric decryption", NULL, 1, NULL);
}
else {
passphrase = smalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd) + 1);
passphrase = smalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd) + 1);
}
symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), salt, 90);
sfree(passphrase);
free(salt);
}
else if(head == PCP_ASYM_CIPHER || head == PCP_ASYM_CIPHER_SIG || head == PCP_ASYM_CIPHER_ANON) {
else if(head == PCP_ASYM_CIPHER || head == PCP_ASYM_CIPHER_SIG
|| head == PCP_ASYM_CIPHER_ANON || head == PCP_ASYM_CIPHER_ANON_SIG) {
/* asymetric mode */
if(useid) {
secret = pcphash_keyexists(ptx, id);
if(secret == NULL) {
fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n",
id, vault->filename);
goto errde3;
}
secret = pcphash_keyexists(ptx, id);
if(secret == NULL) {
fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n",
id, vault->filename);
goto errde3;
}
}
else {
secret = pcp_find_primary_secret();
if(secret == NULL) {
fatal(ptx, "Could not find a secret key in vault %s!\n", id, vault->filename);
goto errde3;
}
secret = pcp_find_primary_secret();
if(secret == NULL) {
fatal(ptx, "Could not find a secret key in vault %s!\n", id, vault->filename);
goto errde3;
}
}
if(secret->secret[0] == 0) {
/* encrypted, decrypt it */
char *passphrase;
if(passwd == NULL) {
pcp_readpass(&passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1, NULL);
}
else {
passphrase = smalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd)+1);
}
secret = pcpkey_decrypt(ptx, secret, passphrase);
sfree(passphrase);
if(secret == NULL)
goto errde3;
char *passphrase;
if(passwd == NULL) {
pcp_readpass(ptx, &passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1, NULL);
}
else {
passphrase = smalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd)+1);
}
if(head == PCP_ASYM_CIPHER_ANON)
anon = 1;
secret = pcpkey_decrypt(ptx, secret, passphrase);
sfree(passphrase);
if(secret == NULL)
goto errde3;
if(head == PCP_ASYM_CIPHER_ANON)
anon = 1;
if(head == PCP_ASYM_CIPHER_SIG)
verify = 1;
if(head == PCP_ASYM_CIPHER_SIG)
verify = 1;
if(head == PCP_ASYM_CIPHER_ANON_SIG) {
anon = 1;
verify = 1;
}
}
else {
@@ -135,6 +139,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
else {
dlen = pcp_decrypt_stream(ptx, pin, pout, NULL, symkey, verify, 0);
sfree(symkey);
symkey = NULL;
}
ps_close(pin);
@@ -151,20 +156,22 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
errde3:
if(symkey != NULL)
free(symkey);
sfree(symkey);
return 1;
}
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt, int armor, int anon) {
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd,
plist_t *recipient, int signcrypt, int armor, int anon) {
FILE *in = NULL;
FILE *out = NULL;
pcp_pubkey_t *pubhash = NULL; /* FIXME: add free() */
pcp_pubkey_t *tmp = NULL;
pcp_pubkey_t *pub = NULL;
pcp_key_t *secret = NULL;
pcp_key_t *signsecret = NULL;
byte *symkey = NULL;
int symmode = 0;
@@ -173,7 +180,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
symmode = 1;
char *passphrase;
if(passwd == NULL) {
pcp_readpass(&passphrase,
pcp_readpass(ptx, &passphrase,
"Enter passphrase for symetric encryption", "Repeat passphrase", 1, NULL);
}
else {
@@ -194,15 +201,15 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
/* self-encryption: look if its a secret one */
pcp_key_t *s = pcphash_keyexists(ptx, id);
if(s != NULL) {
tmp = pcpkey_pub_from_secret(s);
pub = ucmalloc(sizeof(pcp_pubkey_t));
memcpy(pub, tmp, sizeof(pcp_pubkey_t));
HASH_ADD_STR( pubhash, id, pub);
tmp = pcpkey_pub_from_secret(s);
pub = ucmalloc(sizeof(pcp_pubkey_t));
memcpy(pub, tmp, sizeof(pcp_pubkey_t));
HASH_ADD_STR( pubhash, id, pub);
}
else {
fatal(ptx, "Could not find a public key with id 0x%s in vault %s!\n",
id, vault->filename);
goto erren3;
fatal(ptx, "Could not find a public key with id 0x%s in vault %s!\n",
id, vault->filename);
goto erren3;
}
}
else {
@@ -220,15 +227,15 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
pcphash_iteratepub(ptx, tmp) {
rec = recipient->first;
while (rec != NULL) {
_lc(rec->value);
if(strnstr(tmp->mail, rec->value, 255) != NULL
|| strnstr(tmp->owner, rec->value, 255) != NULL) {
pub = ucmalloc(sizeof(pcp_pubkey_t));
memcpy(pub, tmp, sizeof(pcp_pubkey_t));
HASH_ADD_STR( pubhash, id, pub);
/* fprintf(stderr, " => found a matching key %s\n", tmp->id); */
}
rec = rec->next;
_lc(rec->value);
if(strnstr(tmp->mail, rec->value, 255) != NULL
|| strnstr(tmp->owner, rec->value, 255) != NULL) {
pub = ucmalloc(sizeof(pcp_pubkey_t));
memcpy(pub, tmp, sizeof(pcp_pubkey_t));
HASH_ADD_STR( pubhash, id, pub);
/* fprintf(stderr, " => found a matching key %s\n", tmp->id); */
}
rec = rec->next;
}
}
@@ -236,10 +243,10 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
rec = recipient->first;
while (rec != NULL) {
if(strnstr("__self__", rec->value, 13) != NULL) {
pcp_key_t *s = pcp_find_primary_secret();
pcp_pubkey_t *p = pcpkey_pub_from_secret(s);
HASH_ADD_STR( pubhash, id, p);
break;
pcp_key_t *s = pcp_find_primary_secret();
pcp_pubkey_t *p = pcpkey_pub_from_secret(s);
HASH_ADD_STR( pubhash, id, p);
break;
}
rec = rec->next;
}
@@ -253,33 +260,31 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
if(symmode != 1) {
/* we're using a random secret keypair on our side */
if(anon) {
secret = pcpkey_new();
}
else {
if(signcrypt || !anon) {
secret = pcp_find_primary_secret();
if(secret == NULL) {
fatal(ptx, "Could not find a secret key in vault %s!\n", id, vault->filename);
goto erren2;
goto erren2;
}
if(secret->secret[0] == 0) {
/* encrypted, decrypt it */
char *passphrase;
if(passwd == NULL) {
pcp_readpass(&passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1, NULL);
}
else {
passphrase = smalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd)+1);
}
secret = pcpkey_decrypt(ptx, secret, passphrase);
sfree(passphrase);
if(secret == NULL)
goto erren2;
char *passphrase;
if(passwd == NULL) {
pcp_readpass(ptx, &passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1, NULL);
}
else {
passphrase = smalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd)+1);
}
secret = pcpkey_decrypt(ptx, secret, passphrase);
sfree(passphrase);
if(secret == NULL)
goto erren2;
signsecret = secret;
}
if(anon)
secret = pcpkey_new();
}
if(infile == NULL)
@@ -315,7 +320,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
sfree(symkey);
}
else {
clen = pcp_encrypt_stream(ptx, pin, pout, secret, pubhash, signcrypt, anon);
clen = pcp_encrypt_stream(ptx, pin, pout, secret, signsecret, pubhash, signcrypt, anon);
}
if(armor == 1) {
@@ -336,7 +341,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for:\n", (SIZE_T_CAST)clen);
pcp_pubkey_t *cur, *t;
HASH_ITER(hh, pubhash, cur, t) {
fprintf(stderr, " 0x%s - %s <%s>\n", cur->id, cur->owner, cur->mail);
fprintf(stderr, " 0x%s - %s <%s>\n", cur->id, cur->owner, cur->mail);
}
}
if(signcrypt)
@@ -363,16 +368,10 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
void pcpchecksum(char **files, int filenum, char *key) {
int i;
byte *checksum = ucmalloc(crypto_generichash_BYTES_MAX);
byte *keyhash = NULL;
size_t hashlen = 0;
size_t keylen = 0;
if(key != NULL) {
keyhash = ucmalloc(crypto_generichash_BYTES);
crypto_generichash(keyhash, crypto_generichash_BYTES,
(byte *)key, strlen(key),
NULL, crypto_generichash_BYTES);
hashlen = crypto_generichash_BYTES;
}
if(key != NULL)
keylen = strlen(key);
for(i=0; i<filenum; i++) {
FILE *in;
@@ -382,12 +381,12 @@ void pcpchecksum(char **files, int filenum, char *key) {
}
else {
if((in = fopen(files[i], "rb")) == NULL) {
fatal(ptx, "Could not open input file %s\n", files[i]);
break;
fatal(ptx, "Could not open input file %s\n", files[i]);
break;
}
}
Pcpstream *pin = ps_new_file(in);
if(pcp_checksum(ptx, pin, checksum, keyhash, hashlen) > 0) {
if(pcp_checksum(ptx, pin, checksum, (byte *)key, keylen) > 0) {
char *hex = _bin2hex(checksum, crypto_generichash_BYTES_MAX);
fprintf(stdout, "BLAKE2b (%s) = %s\n", files[i], hex);
free(hex);
@@ -397,7 +396,4 @@ void pcpchecksum(char **files, int filenum, char *key) {
}
free(checksum);
if(keyhash != NULL)
free(keyhash);
}

View File

@@ -19,27 +19,28 @@
You can contact me by mail: <tlinden AT cpan DOT org>.
*/
#ifndef _HAVE_ENCRYPTION_H
#define _HAVE_ENCRYPTION_H
#include <stdio.h>
#include <string.h>
#include "context.h"
#include "crypto.h"
#include "defines.h"
#include "key.h"
#include "crypto.h"
#include "keyhash.h"
#include "keyprint.h"
#include "pcp.h"
#include "pcpstream.h"
#include "plist.h"
#include "uthash.h"
#include "z85.h"
#include "keyprint.h"
#include "keyhash.h"
#include "plist.h"
#include "pcpstream.h"
#include "context.h"
int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, int verify);
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt, int armor, int anon);
int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd,
int verify);
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd,
plist_t *recipient, int signcrypt, int armor, int anon);
void pcpchecksum(char **files, int filenum, char *key);
#endif /* _HAVE_ENCRYPTION_H */

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2015 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -19,13 +19,11 @@
You can contact me by mail: <tlinden AT cpan DOT org>.
*/
#include "keymgmt.h"
char *pcp_getstdin(const char *prompt) {
char line[255];
char *out;
char *out = NULL;
fprintf(stderr, "%s: ", prompt);
@@ -43,126 +41,127 @@ char *pcp_getstdin(const char *prompt) {
return out;
errgst:
errgst:
return NULL;
}
int pcp_storekey (pcp_key_t *key) {
if(vault->isnew == 1 || pcphash_count(ptx) == 0) {
int pcp_storekey(pcp_key_t *key) {
if (vault->isnew == 1 || pcphash_count(ptx) == 0) {
key->type = PCP_KEY_TYPE_MAINSECRET;
}
if(pcpvault_addkey(ptx, vault, key, key->type) == 0) {
if(vault->isnew)
if (pcpvault_addkey(ptx, vault, key, key->type) == 0) {
if (vault->isnew)
fprintf(stderr, "new vault created, ");
fprintf(stderr, "key 0x%s added to %s.\n", key->id, vault->filename);
return 0;
}
return 1;
}
void pcp_keygen(char *passwd) {
pcp_key_t *k = pcpkey_new ();
pcp_key_t *k = pcpkey_new();
pcp_key_t *key = NULL;
char *owner = pcp_getstdin("Enter the name of the key owner");
memcpy(k->owner, owner, strlen(owner) + 1);
char *owner = pcp_getstdin("Enter the name of the key owner");
if (owner != NULL)
memcpy(k->owner, owner, strlen(owner) + 1);
char *mail = pcp_getstdin("Enter the email address of the key owner");
memcpy(k->mail, _lc(mail), strlen(mail) + 1);
if (mail != NULL)
memcpy(k->mail, _lc(mail), strlen(mail) + 1);
if(debug)
pcp_dumpkey(k);
if (debug)
pcp_dumpkey(k);
char *passphrase;
if(passwd == NULL) {
pcp_readpass(&passphrase,
"Enter passphrase for key encryption",
"Enter the passphrase again", 1, NULL);
}
else {
passphrase = ucmalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd)+1);
if (passwd == NULL) {
pcp_readpass(ptx, &passphrase, "Enter passphrase for key encryption",
"Enter the passphrase again", 1, NULL);
} else {
passphrase = passwd;
}
if(strnlen(passphrase, 1024) > 0)
key = pcpkey_encrypt(ptx, k, passphrase);
else {
char *yes = pcp_getstdin("WARNING: secret key will be stored unencrypted. Are you sure [yes|NO]?");
if(strncmp(yes, "yes", 1024) == 0)
key = k;
else {
memset(key, 0, sizeof(pcp_key_t));
free(key);
goto errkg1;
if (strnlen(passphrase, 1024) > 0) {
double ent = pcp_getentropy(passphrase);
if (ent < 3.32) {
fprintf(stderr,
"WARNING: you are using a weak passphrase (entropy: %lf)!\n",
ent);
char *yes = pcp_getstdin("Are you sure to use it [yes|NO]?");
if (strncmp(yes, "yes", 1024) != 0) {
goto errkg1;
}
}
key = pcpkey_encrypt(ptx, k, passphrase);
} else {
/* No unencrypted secret key allowed anymore [19.08.2015, tom] */
memset(k, 0, sizeof(pcp_key_t));
free(k);
goto errkg1;
}
if(key != NULL) {
if (key != NULL) {
fprintf(stderr, "Generated new secret key:\n");
if(pcp_storekey(key) == 0) {
if (pcp_storekey(key) == 0) {
pcpkey_printshortinfo(key);
memset(key, 0, sizeof(pcp_key_t));
free(key);
}
}
errkg1:
if (passwd == NULL) {
/* if passwd is set, it'll be free'd in main() */
sfree(passphrase);
}
errkg1:
free(mail);
free(owner);
}
void pcp_listkeys() {
pcp_key_t *k;
int nkeys = pcphash_count(ptx) + pcphash_countpub(ptx);
if(nkeys > 0) {
printf("Key ID Type Creation Time Owner\n");
if (nkeys > 0) {
printf(
"Key ID Type Creation Time Owner\n");
pcphash_iterate(ptx, k) {
pcpkey_printlineinfo(k);
}
pcphash_iterate(ptx, k) { pcpkey_printlineinfo(k); }
pcp_pubkey_t *p;
pcphash_iteratepub(ptx, p) {
pcppubkey_printlineinfo(p);
}
}
else {
fatal(ptx, "The key vault file %s doesn't contain any keys so far.\n", vault->filename);
pcphash_iteratepub(ptx, p) { pcppubkey_printlineinfo(p); }
} else {
fatal(ptx, "The key vault file %s doesn't contain any keys so far.\n",
vault->filename);
}
}
char *pcp_normalize_id(char *keyid) {
char *id = ucmalloc(17);
int len = strnlen(keyid, 24);
if(len == 16) {
if (len == 16) {
memcpy(id, keyid, 17);
}
else if(len < 16) {
} else if (len < 16) {
fatal(ptx, "Specified key id %s is too short!\n", keyid);
free(id);
return NULL;
}
else if(len > 18) {
} else if (len > 18) {
fatal(ptx, "Specified key id %s is too long!\n", keyid);
free(id);
return NULL;
}
else {
if(keyid[0] == '0' && keyid[1] == 'x' && len == 18) {
} else {
if (keyid[0] == '0' && keyid[1] == 'x' && len == 18) {
int i;
for(i=0; i<16; ++i) {
id[i] = keyid[i+2];
for (i = 0; i < 16; ++i) {
id[i] = keyid[i + 2];
}
id[16] = 0;
}
else {
} else {
fatal(ptx, "Specified key id %s is too long!\n", keyid);
free(id);
return NULL;
@@ -175,251 +174,239 @@ char *pcp_normalize_id(char *keyid) {
pcp_key_t *pcp_find_primary_secret() {
pcp_key_t *k;
pcphash_iterate(ptx, k) {
if(k->type == PCP_KEY_TYPE_MAINSECRET) {
if (k->type == PCP_KEY_TYPE_MAINSECRET) {
return k;
}
}
/* no primary? whoops */
int nkeys = pcphash_count(ptx);
if(nkeys == 1) {
pcphash_iterate(ptx, k) {
return k;
}
if (nkeys == 1) {
pcphash_iterate(ptx, k) { return k; }
}
return NULL;
}
void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *passwd) {
void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor,
char *passwd) {
pcp_key_t *key = NULL;
if(useid == 1) {
if (useid == 1) {
/* look if we've got that one */
key = pcphash_keyexists(ptx, keyid);
if(key == NULL) {
fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n", keyid, vault->filename);
if (key == NULL) {
fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n",
keyid, vault->filename);
goto errexpse1;
}
}
else {
} else {
/* look for our primary key */
key = pcp_find_primary_secret();
if(key == NULL) {
fatal(ptx, "There's no primary secret key in the vault %s!\n", vault->filename);
if (key == NULL) {
fatal(ptx, "There's no primary secret key in the vault %s!\n",
vault->filename);
goto errexpse1;
}
}
FILE *out;
if(outfile == NULL) {
if (outfile == NULL) {
out = stdout;
}
else {
if((out = fopen(outfile, "wb+")) == NULL) {
} else {
if ((out = fopen(outfile, "wb+")) == NULL) {
fatal(ptx, "Could not create output file %s\n", outfile);
goto errexpse1;
goto errexpse1;
}
}
if(out != NULL) {
if(debug)
if (out != NULL) {
if (debug)
pcp_dumpkey(key);
if(key->secret[0] == 0) {
/* decrypt the secret key */
if(passwd == NULL) {
char *passphrase;
pcp_readpass(&passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1, NULL);
key = pcpkey_decrypt(ptx, key, passphrase);
if(key == NULL) {
sfree(passphrase);
goto errexpse1;
}
sfree(passphrase);
if (passwd == NULL) {
char *passphrase;
pcp_readpass(ptx, &passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1,
NULL);
key = pcpkey_decrypt(ptx, key, passphrase);
if (key == NULL) {
sfree(passphrase);
goto errexpse1;
}
else {
key = pcpkey_decrypt(ptx, key, passwd);
if(key == NULL) {
goto errexpse1;
}
sfree(passphrase);
} else {
key = pcpkey_decrypt(ptx, key, passwd);
if (key == NULL) {
goto errexpse1;
}
}
Buffer *exported_sk;
if(passwd != NULL) {
if (passwd != NULL) {
exported_sk = pcp_export_secret(ptx, key, passwd);
}
else {
} else {
char *passphrase;
pcp_readpass(&passphrase,
"Enter passphrase to encrypt the exported secret key",
"Repeat passphrase", 1, NULL);
pcp_readpass(ptx, &passphrase,
"Enter passphrase to encrypt the exported secret key",
"Repeat passphrase", 1, NULL);
exported_sk = pcp_export_secret(ptx, key, passphrase);
sfree(passphrase);
}
if(exported_sk != NULL) {
if(armor == 1) {
size_t zlen;
char *z85 = pcp_z85_encode(buffer_get(exported_sk), buffer_size(exported_sk), &zlen, 1);
fprintf(out, "%s\r\n%s\r\n%s\r\n", EXP_SK_HEADER, z85, EXP_SK_FOOTER);
free(z85);
}
else {
fwrite(buffer_get(exported_sk), 1, buffer_size(exported_sk), out);
if (exported_sk != NULL) {
if (armor == 1) {
size_t zlen;
char *z85 = pcp_z85_encode(buffer_get(exported_sk),
buffer_size(exported_sk), &zlen, 1);
fprintf(out, "%s\r\n%s\r\n%s\r\n", EXP_SK_HEADER, z85, EXP_SK_FOOTER);
free(z85);
} else {
fwrite(buffer_get(exported_sk), 1, buffer_size(exported_sk), out);
}
buffer_free(exported_sk);
fprintf(stderr, "secret key exported.\n");
}
}
errexpse1:
;
errexpse1:;
}
/*
if id given, look if it is already a public and export this,
else we look for a secret key with that id. without a given
keyid we use the primary key. if no keyid has been given but
a recipient instead, we try to look up the vault for a match.
*/
void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int armor) {
void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format,
int armor) {
FILE *out;
int is_foreign = 0;
pcp_pubkey_t *pk = NULL;
pcp_key_t *sk = NULL;
Buffer *exported_pk = NULL;
if(outfile == NULL) {
if (outfile == NULL) {
out = stdout;
}
else {
if((out = fopen(outfile, "wb+")) == NULL) {
} else {
if ((out = fopen(outfile, "wb+")) == NULL) {
fatal(ptx, "Could not create output file %s\n", outfile);
goto errpcpexpu1;
}
}
if(keyid != NULL) {
if (keyid != NULL) {
/* keyid specified, check if it exists and if yes, what type it is */
pk = pcphash_pubkeyexists(ptx, keyid);
if(pk == NULL) {
if (pk == NULL) {
/* ok, so, then look for a secret key with that id */
sk = pcphash_keyexists(ptx, keyid);
if(sk == NULL) {
fatal(ptx, "Could not find a key with id 0x%s in vault %s!\n",
keyid, vault->filename);
goto errpcpexpu1;
if (sk == NULL) {
fatal(ptx, "Could not find a key with id 0x%s in vault %s!\n", keyid,
vault->filename);
goto errpcpexpu1;
} else {
/* ok, so it's our own key */
is_foreign = 0;
}
else {
/* ok, so it's our own key */
is_foreign = 0;
}
}
else {
} else {
/* it's a foreign public key, we cannot sign it ourselfes */
is_foreign = 1;
}
}
else {
} else {
/* we use our primary key anyway */
sk = pcp_find_primary_secret();
if(sk == NULL) {
fatal(ptx, "There's no primary secret key in the vault %s!\n", vault->filename);
if (sk == NULL) {
fatal(ptx, "There's no primary secret key in the vault %s!\n",
vault->filename);
goto errpcpexpu1;
}
is_foreign = 0;
}
if(is_foreign == 0 && sk->secret[0] == 0 && format <= EXP_FORMAT_PBP) {
if (is_foreign == 0 && sk->secret[0] == 0 && format <= EXP_FORMAT_PBP) {
/* decrypt the secret key */
if(passwd != NULL) {
if (passwd != NULL) {
sk = pcpkey_decrypt(ptx, sk, passwd);
}
else {
} else {
char *passphrase;
pcp_readpass(&passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1, NULL);
pcp_readpass(ptx, &passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1,
NULL);
sk = pcpkey_decrypt(ptx, sk, passphrase);
sfree(passphrase);
}
if(sk == NULL) {
if (sk == NULL) {
goto errpcpexpu1;
}
}
/* now, we're ready for the actual export */
if(format == EXP_FORMAT_NATIVE) {
if(is_foreign == 0) {
if (format == EXP_FORMAT_NATIVE) {
if (is_foreign == 0) {
exported_pk = pcp_export_rfc_pub(ptx, sk);
if(exported_pk != NULL) {
if(armor == 1) {
size_t zlen;
char *z85 = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen, 1);
fprintf(out, "%s\r\n%s\r\n%s\r\n", EXP_PK_HEADER, z85, EXP_PK_FOOTER);
free(z85);
}
else
fwrite(buffer_get(exported_pk), 1, buffer_size(exported_pk), out);
buffer_free(exported_pk);
fprintf(stderr, "public key exported.\n");
if (exported_pk != NULL) {
if (armor == 1) {
size_t zlen;
char *z85 = pcp_z85_encode(buffer_get(exported_pk),
buffer_size(exported_pk), &zlen, 1);
fprintf(out, "%s\r\n%s\r\n%s\r\n", EXP_PK_HEADER, z85, EXP_PK_FOOTER);
free(z85);
} else
fwrite(buffer_get(exported_pk), 1, buffer_size(exported_pk), out);
buffer_free(exported_pk);
fprintf(stderr, "public key exported.\n");
}
}
else {
} else {
/* FIXME: export foreign keys unsupported yet */
fatal(ptx, "Exporting foreign public keys in native format unsupported yet\n");
fatal(ptx,
"Exporting foreign public keys in native format unsupported yet\n");
goto errpcpexpu1;
}
}
else if(format == EXP_FORMAT_PBP) {
if(is_foreign == 0) {
} else if (format == EXP_FORMAT_PBP) {
if (is_foreign == 0) {
exported_pk = pcp_export_pbp_pub(sk);
if(exported_pk != NULL) {
/* PBP format requires armoring always */
size_t zlen;
char *z85pbp = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen, 1);
fprintf(out, "%s", z85pbp);
free(z85pbp);
buffer_free(exported_pk);
fprintf(stderr, "public key exported in PBP format.\n");
if (exported_pk != NULL) {
/* PBP format requires armoring always */
size_t zlen;
char *z85pbp = pcp_z85_encode(buffer_get(exported_pk),
buffer_size(exported_pk), &zlen, 1);
fprintf(out, "%s", z85pbp);
free(z85pbp);
buffer_free(exported_pk);
fprintf(stderr, "public key exported in PBP format.\n");
}
}
else {
} else {
fatal(ptx, "Exporting foreign public keys in PBP format not possible\n");
goto errpcpexpu1;
}
}
errpcpexpu1:
;
errpcpexpu1:;
}
void pcpdelete_key(char *keyid) {
pcp_pubkey_t *p = pcphash_pubkeyexists(ptx, keyid);
if(p != NULL) {
if (p != NULL) {
/* delete public */
pcp_keysig_t *sig = pcphash_keysigexists(ptx, keyid);
if (sig != NULL) {
/* also delete associted sig, if any */
pcphash_del(ptx, sig, sig->type);
}
pcphash_del(ptx, p, p->type);
vault->unsafed = 1;
fprintf(stderr, "Public key deleted.\n");
}
else {
} else {
pcp_key_t *s = pcphash_keyexists(ptx, keyid);
if(s != NULL) {
if (s != NULL) {
/* delete secret */
pcphash_del(ptx, s, s->type);
vault->unsafed = 1;
fprintf(stderr, "Secret key deleted.\n");
}
else {
} else {
fatal(ptx, "No key with id 0x%s found!\n", keyid);
}
}
@@ -428,95 +415,99 @@ void pcpdelete_key(char *keyid) {
void pcpedit_key(char *keyid) {
pcp_key_t *key = pcphash_keyexists(ptx, keyid);
if(key != NULL) {
if(key->secret[0] == 0) {
if (key != NULL) {
if (key->secret[0] == 0) {
char *passphrase;
pcp_readpass(&passphrase, "Enter passphrase to decrypt the key", NULL, 1, NULL);
pcp_readpass(ptx, &passphrase, "Enter passphrase to decrypt the key",
NULL, 1, NULL);
key = pcpkey_decrypt(ptx, key, passphrase);
sfree(passphrase);
}
if(key != NULL) {
if (key != NULL) {
fprintf(stderr, "Current owner: %s\n", key->owner);
char *owner = pcp_getstdin(" enter new name or press enter to keep current");
if(strlen(owner) > 0)
memcpy(key->owner, owner, strlen(owner) + 1);
char *owner =
pcp_getstdin(" enter new name or press enter to keep current");
if (strlen(owner) > 0)
memcpy(key->owner, owner, strlen(owner) + 1);
fprintf(stderr, "Current mail: %s\n", key->mail);
char *mail = pcp_getstdin(" enter new email or press enter to keep current");
if(strlen(mail) > 0)
memcpy(key->mail, mail, strlen(mail) + 1);
char *mail =
pcp_getstdin(" enter new email or press enter to keep current");
if (strlen(mail) > 0)
memcpy(key->mail, mail, strlen(mail) + 1);
free(owner);
free(mail);
if(key->type != PCP_KEY_TYPE_MAINSECRET) {
pcp_key_t *other = NULL;
uint8_t haveprimary = 0;
pcphash_iterate(ptx, other) {
if(other->type == PCP_KEY_TYPE_MAINSECRET) {
haveprimary = 1;
break;
}
}
if (key->type != PCP_KEY_TYPE_MAINSECRET) {
pcp_key_t *other = NULL;
uint8_t haveprimary = 0;
pcphash_iterate(ptx, other) {
if (other->type == PCP_KEY_TYPE_MAINSECRET) {
haveprimary = 1;
break;
}
}
char *yes = NULL;
if(! haveprimary) {
fprintf(stderr, "There is currently no primary secret in your vault,\n");
yes = pcp_getstdin("want to make this one the primary [yes|NO]?");
}
else {
fprintf(stderr, "The key %s is currently the primary secret,\n", other->id);
yes = pcp_getstdin("want to make this one the primary instead [yes|NO]?");
}
char *yes = NULL;
if (!haveprimary) {
fprintf(stderr,
"There is currently no primary secret in your vault,\n");
yes = pcp_getstdin("want to make this one the primary [yes|NO]?");
} else {
fprintf(stderr, "The key %s is currently the primary secret,\n",
other->id);
yes = pcp_getstdin(
"want to make this one the primary instead [yes|NO]?");
}
if(strncmp(yes, "yes", 1024) == 0) {
key->type = PCP_KEY_TYPE_MAINSECRET;
if(haveprimary) {
fprintf(stderr, "other type: %d\n", other->type);
other->type = PCP_KEY_TYPE_SECRET;
fprintf(stderr, " new type: %d\n", other->type);
}
}
free(yes);
if (strncmp(yes, "yes", 1024) == 0) {
key->type = PCP_KEY_TYPE_MAINSECRET;
if (haveprimary) {
fprintf(stderr, "other type: %d\n", other->type);
other->type = PCP_KEY_TYPE_SECRET;
fprintf(stderr, " new type: %d\n", other->type);
}
}
free(yes);
}
char *passphrase;
pcp_readpass(&passphrase,
"Enter new passphrase for key encryption (press enter to keep current)",
"Enter the passphrase again", 1, NULL);
pcp_readpass(ptx, &passphrase,
"Enter new passphrase for key encryption (press enter to "
"keep current)",
"Enter the passphrase again", 1, NULL);
if(strnlen(passphrase, 1024) > 0) {
key = pcpkey_encrypt(ptx, key, passphrase);
sfree(passphrase);
if (strnlen(passphrase, 1024) > 0) {
key = pcpkey_encrypt(ptx, key, passphrase);
sfree(passphrase);
}
if(key != NULL) {
if(debug)
pcp_dumpkey(key);
if (key != NULL) {
if (debug)
pcp_dumpkey(key);
vault->unsafed = 1; /* will be safed automatically */
fprintf(stderr, "Key %s changed.\n", key->id);
vault->unsafed = 1; /* will be safed automatically */
fprintf(stderr, "Key %s changed.\n", key->id);
}
}
}
else {
} else {
fatal(ptx, "No key with id 0x%s found!\n", keyid);
}
}
char *pcp_find_id_byrec(char *recipient) {
pcp_pubkey_t *p;
char *id = NULL;
_lc(recipient);
pcphash_iteratepub(ptx, p) {
if(strncmp(p->owner, recipient, 255) == 0) {
if (strncmp(p->owner, recipient, 255) == 0) {
id = ucmalloc(17);
strncpy(id, p->id, 17);
break;
}
if(strncmp(p->mail, recipient, 255) == 0) {
if (strncmp(p->mail, recipient, 255) == 0) {
id = ucmalloc(17);
strncpy(id, p->id, 17);
break;
@@ -525,8 +516,7 @@ char *pcp_find_id_byrec(char *recipient) {
return id;
}
int pcp_import (vault_t *vault, FILE *in, char *passwd) {
int pcp_import(vault_t *vault, FILE *in, char *passwd) {
byte *buf = ucmalloc(PCP_BLOCK_SIZE);
size_t bufsize;
pcp_pubkey_t *pub = NULL;
@@ -540,137 +530,134 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
bufsize = ps_read(pin, buf, PCP_BLOCK_SIZE);
if(bufsize == 0) {
if (bufsize == 0) {
fatal(ptx, "Input file is empty!\n");
goto errimp1;
}
/* first try as rfc pub key */
bundle = pcp_import_binpub(ptx, buf, bufsize);
if(bundle != NULL) {
if (bundle != NULL) {
keysig = bundle->s;
pub = bundle->p;
if(debug)
if (debug)
pcp_dumppubkey(pub);
if(keysig == NULL) {
if (keysig == NULL) {
fatals_ifany(ptx);
char *yes = pcp_getstdin("WARNING: signature doesn't verify, import anyway [yes|NO]?");
if(strncmp(yes, "yes", 1024) != 0) {
free(yes);
goto errimp2;
char *yes = pcp_getstdin(
"WARNING: signature doesn't verify, import anyway [yes|NO]?");
if (strncmp(yes, "yes", 1024) != 0) {
free(yes);
goto errimp2;
}
free(yes);
}
if(pcp_sanitycheck_pub(ptx, pub) == 0) {
if(pcpvault_addkey(ptx, vault, (void *)pub, PCP_KEY_TYPE_PUBLIC) == 0) {
fprintf(stderr, "key 0x%s added to %s.\n", pub->id, vault->filename);
/* avoid double free */
success = 0;
if (pcp_sanitycheck_pub(ptx, pub) == 0) {
if (pcpvault_addkey(ptx, vault, (void *)pub, PCP_KEY_TYPE_PUBLIC) == 0) {
fprintf(stderr, "key 0x%s added to %s.\n", pub->id, vault->filename);
/* avoid double free */
success = 0;
} else
goto errimp2;
if (keysig != NULL) {
if (pcpvault_addkey(ptx, vault, keysig, keysig->type) != 0) {
/* FIXME: remove pubkey if storing the keysig failed */
goto errimp2;
}
}
else
goto errimp2;
if(keysig != NULL) {
if(pcpvault_addkey(ptx, vault, keysig, keysig->type) != 0) {
/* FIXME: remove pubkey if storing the keysig failed */
goto errimp2;
}
}
}
else
} else
goto errimp2;
}
else {
} else {
/* it's not public key, so let's try to interpret it as secret key */
if(ptx->verbose)
if (ptx->verbose)
fatals_ifany(ptx);
if(passwd != NULL) {
if (passwd != NULL) {
sk = pcp_import_secret(ptx, buf, bufsize, passwd);
}
else {
} else {
char *passphrase;
pcp_readpass(&passphrase,
"Enter passphrase to decrypt the secret key file", NULL, 1, NULL);
pcp_readpass(ptx, &passphrase,
"Enter passphrase to decrypt the secret key file", NULL, 1,
NULL);
sk = pcp_import_secret(ptx, buf, bufsize, passphrase);
sfree(passphrase);
}
if(sk == NULL) {
if (sk == NULL) {
goto errimp2;
}
if(debug)
if (debug)
pcp_dumpkey(sk);
pcp_key_t *maybe = pcphash_keyexists(ptx, sk->id);
if(maybe != NULL) {
fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", sk->id);
if (maybe != NULL) {
fatal(ptx,
"Secretkey sanity check: there already exists a key with the id "
"0x%s\n",
sk->id);
goto errimp2;
}
/* store it */
if(passwd != NULL) {
if (passwd != NULL) {
sk = pcpkey_encrypt(ptx, sk, passwd);
}
else {
} else {
char *passphrase;
pcp_readpass(&passphrase,
"Enter passphrase for key encryption",
"Enter the passphrase again", 1, NULL);
if(strnlen(passphrase, 1024) > 0) {
/* encrypt the key */
sk = pcpkey_encrypt(ptx, sk, passphrase);
sfree(passphrase);
}
else {
/* ask for confirmation if we shall store it in the clear */
char *yes = pcp_getstdin(
"WARNING: secret key will be stored unencrypted. Are you sure [yes|NO]?");
if(strncmp(yes, "yes", 1024) != 0) {
free(yes);
goto errimp1;
}
free(yes);
pcp_readpass(ptx, &passphrase, "Enter passphrase for key encryption",
"Enter the passphrase again", 1, NULL);
if (strnlen(passphrase, 1024) > 0) {
/* encrypt the key */
sk = pcpkey_encrypt(ptx, sk, passphrase);
sfree(passphrase);
} else {
/* ask for confirmation if we shall store it in the clear */
char *yes = pcp_getstdin("WARNING: secret key will be stored "
"unencrypted. Are you sure [yes|NO]?");
if (strncmp(yes, "yes", 1024) != 0) {
free(yes);
goto errimp1;
}
free(yes);
}
}
if(sk != NULL) {
if (sk != NULL) {
/* store it to the vault if we got it til here */
if(pcp_sanitycheck_key(ptx, sk) == 0) {
if(pcp_storekey(sk) == 0) {
pcpkey_printshortinfo(sk);
success = 0;
}
if (pcp_sanitycheck_key(ptx, sk) == 0) {
if (pcp_storekey(sk) == 0) {
pcpkey_printshortinfo(sk);
success = 0;
}
}
}
}
errimp2:
if(keysig != NULL) {
if (keysig != NULL) {
ucfree(keysig->blob, keysig->size);
ucfree(keysig, sizeof(pcp_keysig_t));
}
if(bundle != NULL) {
if (bundle != NULL) {
free(bundle);
}
if(pub != NULL) {
if (pub != NULL) {
ucfree(pub, sizeof(pcp_pubkey_t));
}
if(sk != NULL) {
if (sk != NULL) {
ucfree(sk, sizeof(pcp_key_t));
}
ucfree(buf, bufsize);
errimp1:
errimp1:
ps_close(pin);
return success;

View File

@@ -19,44 +19,44 @@
You can contact me by mail: <tlinden AT cpan DOT org>.
*/
#ifndef _HAVE_KEYMGMT_H
#define _HAVE_KEYMGMT_H
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <wctype.h>
#include "randomart.h"
#include "key.h"
#include "pcp.h"
#include "vault.h"
#include "defines.h"
#include "readpass.h"
#include "keyprint.h"
#include "keyhash.h"
#include "util.h"
#include "buffer.h"
#include "mgmt.h"
#include "context.h"
#include "defines.h"
#include "key.h"
#include "keyhash.h"
#include "keyprint.h"
#include "mgmt.h"
#include "randomart.h"
#include "readpass.h"
#include "util.h"
#include "vault.h"
#define _WITH_GETLINE
char *pcp_getstdin(const char *prompt);
int pcp_storekey (pcp_key_t *key);
int pcp_storekey(pcp_key_t *key);
void pcp_keygen(char *passwd);
void pcp_listkeys();
void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *passwd);
void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int armor);
void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor,
char *passwd);
void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format,
int armor);
pcp_key_t *pcp_getrsk(pcp_key_t *s, char *recipient, char *passwd);
char *pcp_normalize_id(char *keyid);
pcp_key_t *pcp_find_primary_secret();
int pcp_import (vault_t *vault, FILE *in, char *passwd);
int pcp_import(vault_t *vault, FILE *in, char *passwd);
void pcpdelete_key(char *keyid);
char *pcp_find_id_byrec(char *recipient);

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013 T.Linden.
Copyright (C) 2013-2016 T.v.Dein.
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
@@ -92,13 +92,13 @@ void pcptext_key(char *keyid) {
pcp_pubkey_t *p = pcphash_pubkeyexists(ptx, keyid);
if(p != NULL) {
if(debug) {
pcp_dumppubkey(p);
pcp_keysig_t *s = pcphash_keysigexists(ptx, keyid);
if(s != NULL) {
printf("\n");
pcp_dumpkeysig(s);
}
printf("\n");
pcp_dumppubkey(p);
pcp_keysig_t *s = pcphash_keysigexists(ptx, keyid);
if(s != NULL) {
printf("\n");
pcp_dumpkeysig(s);
}
printf("\n");
}
pcppubkey_print(p, stdout);
}
@@ -109,64 +109,66 @@ void pcptext_key(char *keyid) {
}
void pcptext_vault(vault_t *vault) {
if(vault != NULL) {
#ifdef HAVE_JSON
if(ptx->json) {
json_t *jout, *jkeys, *jtmp;
char *checksum, *jdump;
pcp_key_t *k;
pcp_pubkey_t *p;
if(ptx->json) {
json_t *jout, *jkeys, *jtmp;
char *checksum, *jdump;
pcp_key_t *k;
pcp_pubkey_t *p;
checksum = _bin2hex(vault->checksum, 32);
jout = json_pack("{sssisssisi}",
"keyvaultfile", vault->filename,
"version", vault->version,
"checksum", checksum,
"secretkeys", pcphash_count(ptx),
"publickey", pcphash_countpub(ptx));
checksum = _bin2hex(vault->checksum, LSHA);
jout = json_pack("{sssisssisi}",
"keyvaultfile" , vault->filename,
"version" , vault->version,
"checksum" , checksum,
"secretkeys" , pcphash_count(ptx),
"publickey" , pcphash_countpub(ptx));
jkeys = json_array();
jkeys = json_array();
pcphash_iterate(ptx, k) {
jtmp = pcp_sk2json(k, NULL, 0);
json_object_set(jtmp, "type", json_string("secret"));
json_array_append(jkeys, jtmp);
pcphash_iterate(ptx, k) {
jtmp = pcp_sk2json(k, NULL, 0);
json_object_set(jtmp, "type", json_string("secret"));
json_array_append(jkeys, jtmp);
}
pcphash_iteratepub(ptx, p) {
jtmp = pcp_pk2json(p);
json_array_append(jkeys, jtmp);
}
json_object_set(jout, "keys", jkeys);
jdump = json_dumps(jout, JSON_INDENT(4) | JSON_PRESERVE_ORDER);
printf("%s\n", jdump);
json_decref(jout);
free(jdump);
}
pcphash_iteratepub(ptx, p) {
jtmp = pcp_pk2json(p);
json_array_append(jkeys, jtmp);
}
json_object_set(jout, "keys", jkeys);
jdump = json_dumps(jout, JSON_INDENT(4) | JSON_PRESERVE_ORDER);
printf("%s\n", jdump);
json_decref(jout);
free(jdump);
}
else {
else {
#endif
printf(" Key vault: %s\n", vault->filename);
printf("Vault version: %08X\n", vault->version);
printf(" Checksum: ");
printf(" Key vault: %s\n", vault->filename);
printf("Vault version: %08X\n", vault->version);
printf(" Checksum: ");
int i;
for ( i = 0;i <15 ;++i) printf("%02X:",(unsigned int) vault->checksum[i]);
printf("%02X", vault->checksum[15]);
printf("\n ");
for ( i = 16;i <31 ;++i) printf("%02X:",(unsigned int) vault->checksum[i]);
printf("%02X", vault->checksum[31]);
printf("\n");
int i;
for ( i = 0;i <15 ;++i) printf("%02X:",(unsigned int) vault->checksum[i]);
printf("%02X", vault->checksum[15]);
printf("\n ");
for ( i = 16;i <31 ;++i) printf("%02X:",(unsigned int) vault->checksum[i]);
printf("%02X", vault->checksum[31]);
printf("\n");
printf(" Secret keys: %d\n", pcphash_count(ptx));
printf(" Public keys: %d\n", pcphash_countpub(ptx) );
printf(" Secret keys: %d\n", pcphash_count(ptx));
printf(" Public keys: %d\n", pcphash_countpub(ptx) );
#ifdef HAVE_JSON
}
}
#endif
}
}
void pcpkey_printlineinfo(pcp_key_t *key) {
@@ -174,26 +176,26 @@ void pcpkey_printlineinfo(pcp_key_t *key) {
time_t t = (time_t)key->ctime;
c = localtime(&t);
printf("0x%s %s %04d-%02d-%02dT%02d:%02d:%02d %s <%s>\n",
key->id,
(key->type == PCP_KEY_TYPE_MAINSECRET) ? "primary secret" : "secret ",
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
c->tm_hour, c->tm_min, c->tm_sec,
key->owner, key->mail);
key->id,
(key->type == PCP_KEY_TYPE_MAINSECRET) ? "primary secret" : "secret ",
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
c->tm_hour, c->tm_min, c->tm_sec,
key->owner, key->mail);
if(ptx->verbose) {
printf(" ");
byte *hash = pcpkey_getchecksum(key);
int i, y;
for(i=0; i<32; i+=4) {
for(i=0; i<LSHA; i+=4) {
for(y=0; y<4; y++) {
printf("%02x", hash[i+y]);
printf("%02x", hash[i+y]);
}
printf(" ");
}
free(hash);
printf("\n encrypted: %s, serial: %08x, version: %d\n",
(key->secret[0] == '\0') ? "yes" : " no",
key->serial, (int)key->version);
(key->secret[0] == '\0') ? "yes" : " no",
key->serial, (int)key->version);
printf("\n");
}
}
@@ -203,35 +205,35 @@ void pcppubkey_printlineinfo(pcp_pubkey_t *key) {
time_t t = (time_t)key->ctime;
c = localtime(&t);
printf("0x%s %s %04d-%02d-%02dT%02d:%02d:%02d %s <%s>\n",
key->id,
(key->valid == 1) ? "valid public " : "public ",
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
c->tm_hour, c->tm_min, c->tm_sec,
key->owner, key->mail);
key->id,
(key->valid == 1) ? "valid public " : "public ",
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
c->tm_hour, c->tm_min, c->tm_sec,
key->owner, key->mail);
if(ptx->verbose) {
printf(" ");
byte *hash = pcppubkey_getchecksum(key);
int i, y;
for(i=0; i<32; i+=4) {
for(i=0; i<LSHA; i+=4) {
for(y=0; y<4; y++) {
printf("%02x", hash[i+y]);
printf("%02x", hash[i+y]);
}
printf(" ");
}
free(hash);
printf("\n signed: %s, serial: %08x, version: %d, ",
(key->valid == 1) ? "yes" : " no",
key->serial, (int)key->version);
(key->valid == 1) ? "yes" : " no",
key->serial, (int)key->version);
pcp_keysig_t *sig = pcphash_keysigexists(ptx, key->id);
if(sig != NULL) {
printf("signature fingerprint:\n ");
byte *checksum = sig->checksum;
for(i=0; i<32; i+=4) {
for(y=0; y<4; y++) {
printf("%02x", checksum[i+y]);
}
printf(" ");
for(i=0; i<LSHA; i+=4) {
for(y=0; y<4; y++) {
printf("%02x", checksum[i+y]);
}
printf(" ");
}
printf("\n");
}
@@ -253,7 +255,7 @@ void pcppubkey_print(pcp_pubkey_t *key, FILE* out) {
jout = pcp_pk2json(key);
json_object_set(jout, "random-art-id", json_string(r));
jdump = json_dumps(jout, JSON_INDENT(4) | JSON_PRESERVE_ORDER);
fprintf(out, "%s\n", jdump);
json_decref(jout);
@@ -274,12 +276,12 @@ void pcppubkey_print(pcp_pubkey_t *key, FILE* out) {
fprintf(out, " Mail: %s\n", key->mail);
fprintf(out, " Key-ID: 0x%s\n", key->id);
fprintf(out, " Public-Key: %s\n", pcp_z85_encode(key->pub, 32, &zlen, 1));
fprintf(out, " Public-Key: %s\n", pcp_z85_encode(key->pub, LBOXPUB, &zlen, 1));
/* 2004-06-14T23:34:30. */
fprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n",
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
c->tm_hour, c->tm_min, c->tm_sec);
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
c->tm_hour, c->tm_min, c->tm_sec);
byte *hash = pcppubkey_getchecksum(key);
fprintf(out, " Checksum: ");
@@ -298,10 +300,10 @@ void pcppubkey_print(pcp_pubkey_t *key, FILE* out) {
size_t rlen = strlen(r);
for (i=0; i<rlen; ++i) {
if(r[i] == '\n') {
fprintf(out, "\n ");
fprintf(out, "\n ");
}
else {
fprintf(out, "%c", r[i]);
fprintf(out, "%c", r[i]);
}
}
fprintf(out, "\n");
@@ -327,7 +329,7 @@ void pcpkey_print(pcp_key_t *key, FILE* out) {
jout = pcp_sk2json(key, NULL, 0);
json_object_set(jout, "type", json_string("secret"));
json_object_set(jout, "random-art-id", json_string(r));
jdump = json_dumps(jout, JSON_INDENT(4) | JSON_PRESERVE_ORDER);
fprintf(out, "%s\n", jdump);
json_decref(jout);
@@ -349,8 +351,8 @@ void pcpkey_print(pcp_key_t *key, FILE* out) {
/* 2004-06-14T23:34:30. */
fprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n",
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
c->tm_hour, c->tm_min, c->tm_sec);
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
c->tm_hour, c->tm_min, c->tm_sec);
fprintf(out, " Serial Number: 0x%08X\n", key->serial);
fprintf(out, " Key Version: 0x%08X\n", key->version);
@@ -359,10 +361,10 @@ void pcpkey_print(pcp_key_t *key, FILE* out) {
size_t rlen = strlen(r);
for (i=0; i<rlen; ++i) {
if(r[i] == '\n') {
fprintf(out, "\n ");
fprintf(out, "\n ");
}
else {
fprintf(out, "%c", r[i]);
fprintf(out, "%c", r[i]);
}
}
fprintf(out, "\n");

858
src/pcp.c

File diff suppressed because it is too large Load Diff

View File

@@ -19,58 +19,58 @@
You can contact me by mail: <tlinden AT cpan DOT org>.
*/
#ifndef _HAVE_PCP_H
#define _HAVE_PCP_H
#include <unistd.h>
#include <compat_getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <compat_getopt.h>
#include <unistd.h>
#ifndef DEBUG
# ifdef HAVE_SETRLIMIT
# include <sys/types.h>
# include <sys/time.h>
# include <sys/resource.h>
# endif
#ifdef HAVE_SETRLIMIT
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#endif
#endif
/* lib */
#include "mem.h"
#include "z85.h"
#include "zmq_z85.h"
#include "z85util.h"
#include "version.h"
#include "vault.h"
#include "context.h"
#include "mem.h"
#include "vault.h"
#include "version.h"
#include "z85.h"
#include "z85util.h"
#include "zmq_z85.h"
/* subs */
#include "keymgmt.h"
#include "usage.h"
#include "encryption.h"
#include "signature.h"
#include "keyhash.h"
#include "keymgmt.h"
#include "plist.h"
#include "signature.h"
#include "usage.h"
/* operation modi */
/* perl -e '$x=0; while ($x<100000) { $x++; $x *= 1.7; printf "0x%08X: %d\n", $x, $x }' */
#define PCP_MODE_KEYGEN 0x00000001
#define PCP_MODE_LISTKEYS 0x00000004
/* perl -e '$x=0; while ($x<100000) { $x++; $x *= 1.7; printf "0x%08X: %d\n",
* $x, $x }' */
#define PCP_MODE_KEYGEN 0x00000001
#define PCP_MODE_LISTKEYS 0x00000004
#define PCP_MODE_EXPORT_SECRET 0x00000009
#define PCP_MODE_EXPORT_PUBLIC 0x00000011
#define PCP_MODE_IMPORT 0x00000020
#define PCP_MODE_ENCRYPT_ME 0x00000038
#define PCP_MODE_DELETE_KEY 0x00000061
#define PCP_MODE_TEXT 0x000000A6
#define PCP_MODE_EDIT 0x0000011D
#define PCP_MODE_ENCRYPT 0x000001E7
#define PCP_MODE_DECRYPT 0x0000033D
#define PCP_MODE_ZENCODE 0x00000584
#define PCP_MODE_ZDECODE 0x00000962
#define PCP_MODE_SIGN 0x00000FF6
#define PCP_MODE_VERIFY 0x00001B25
#define PCP_MODE_CHECKSUM 0x00002E27
#define PCP_MODE_IMPORT 0x00000020
#define PCP_MODE_ENCRYPT_ME 0x00000038
#define PCP_MODE_DELETE_KEY 0x00000061
#define PCP_MODE_TEXT 0x000000A6
#define PCP_MODE_EDIT 0x0000011D
#define PCP_MODE_ENCRYPT 0x000001E7
#define PCP_MODE_DECRYPT 0x0000033D
#define PCP_MODE_ZENCODE 0x00000584
#define PCP_MODE_ZDECODE 0x00000962
#define PCP_MODE_SIGN 0x00000FF6
#define PCP_MODE_VERIFY 0x00001B25
#define PCP_MODE_CHECKSUM 0x00002E27
/*
0x00001B25
@@ -82,13 +82,16 @@
0x00028F70
*/
#define PCP_HELP_INTRO "This is Pretty Curved Privacy. Licensed under the GPLv3. This is\n" \
"BETA software. Use with care. NOT intended for production use.\n"
#define PCP_HELP_INTRO \
"This is Pretty Curved Privacy. Licensed under the GPLv3. This is\n" \
"BETA software. Use with care. NOT intended for production use.\n"
#define LONG_EXTPASS 515
/* some globals */
vault_t *vault;
PCPCTX *ptx;
int debug;
extern vault_t *vault;
extern PCPCTX *ptx;
extern int debug;
void version();
void usage();

View File

@@ -1,156 +0,0 @@
/*-
* Copyright 2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "readpass.h"
/**
* tarsnap_getpass(passwd, prompt, confirmprompt, devtty)
* If ${devtty} is non-zero, read a password from /dev/tty if possible; if
* not, read from stdin. If reading from a tty (either /dev/tty or stdin),
* disable echo and prompt the user by printing ${prompt} to stderr. If
* ${confirmprompt} is non-NULL, read a second password (prompting if a
* terminal is being used) and repeat until the user enters the same password
* twice. Return the password as a malloced NUL-terminated string via
* ${passwd}. The obscure name is to avoid namespace collisions due to the
* getpass / readpass / readpassphrase / etc. functions in various libraries.
*/
int
pcp_readpass(char ** passwd, const char * prompt,
const char * confirmprompt, int devtty, char *readfromfile)
{
FILE * readfrom;
char passbuf[MAXPASSLEN];
char confpassbuf[MAXPASSLEN];
struct termios term, term_old;
int usingtty;
/*
* If devtty != 0, try to open /dev/tty; if that fails, or if devtty
* is zero, we'll read the password from stdin instead.
*
* Added by tlinden: however, if readfromfile is defined, we'll
* read the password from there, but if it is '-' we'll use stdin
* as well.
*/
if ((devtty == 0) || ((readfrom = fopen("/dev/tty", "r")) == NULL)) {
if(readfromfile != NULL) {
if(readfromfile[0] == '-') {
readfrom = stdin;
}
else {
if((readfrom = fopen(readfromfile, "r")) == NULL) {
fatal(ptx, "Could not open password file '%s'\n", readfromfile);
goto err1;
}
}
}
else {
readfrom = stdin;
}
}
/* If we're reading from a terminal, try to disable echo. */
if ((usingtty = isatty(fileno(readfrom))) != 0) {
if (tcgetattr(fileno(readfrom), &term_old)) {
fatal(ptx, "Cannot read terminal settings\n");
goto err1;
}
memcpy(&term, &term_old, sizeof(struct termios));
term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL;
if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
fatal(ptx, "Cannot set terminal settings\n");
goto err1;
}
}
retry:
/* If we have a terminal, prompt the user to enter the password. */
if (usingtty)
fprintf(stderr, "%s: ", prompt);
/* Read the password. */
if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
fatal(ptx, "Cannot read password\n");
goto err2;
}
/* Confirm the password if necessary. */
if (confirmprompt != NULL) {
if (usingtty)
fprintf(stderr, "%s: ", confirmprompt);
if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) {
fatal(ptx, "Cannot read password\n");
goto err2;
}
if (strcmp(passbuf, confpassbuf)) {
fprintf(stderr,
"Passwords mismatch, please try again\n");
goto retry;
}
}
/* Terminate the string at the first "\r" or "\n" (if any). */
passbuf[strcspn(passbuf, "\r\n")] = '\0';
/* If we changed terminal settings, reset them. */
if (usingtty)
tcsetattr(fileno(readfrom), TCSANOW, &term_old);
/* Close /dev/tty if we opened it.
if readfromfile is defined and set to -, disable stdin */
if (readfrom != stdin) {
fclose(readfrom);
}
else {
if(readfromfile != NULL)
stdin = NULL;
}
/* Copy the password out. */
char *p = smalloc(strlen(passbuf) + 1);
memcpy(p, passbuf, strlen(passbuf) + 1 );
*passwd = p;
/* Zero any stored passwords. */
memset(passbuf, 0, MAXPASSLEN);
memset(confpassbuf, 0, MAXPASSLEN);
/* Success! */
return (0);
err2:
/* Reset terminal settings if necessary. */
if (usingtty)
tcsetattr(fileno(readfrom), TCSAFLUSH, &term_old);
err1:
/* Close /dev/tty if we opened it. */
if (readfrom != stdin)
fclose(readfrom);
/* Failure! */
return (-1);
}

View File

@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2015 T.Linden.
Copyright (C) 2013-2016 T.Linden.
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
@@ -54,23 +54,20 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
}
}
if(secret->secret[0] == 0) {
/* encrypted, decrypt it */
char *passphrase;
if(passwd == NULL) {
pcp_readpass(&passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1, NULL);
}
else {
passphrase = smalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd)+1);
}
secret = pcpkey_decrypt(ptx, secret, passphrase);
sfree(passphrase);
if(secret == NULL)
goto errs1;
char *passphrase;
if(passwd == NULL) {
pcp_readpass(ptx, &passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1, NULL);
}
else {
passphrase = smalloc(strlen(passwd)+1);
memcpy(passphrase, passwd, strlen(passwd)+1);
}
secret = pcpkey_decrypt(ptx, secret, passphrase);
sfree(passphrase);
if(secret == NULL)
goto errs1;
Pcpstream *pin = ps_new_file(in);
Pcpstream *pout = ps_new_file(out);

View File

@@ -16,7 +16,10 @@
"-V --vault <vaultfile> Specify an alternate vault file.\n" \
"-O --outfile <file> Output file. STDOUT if unspecified.\n" \
"-I --infile <file> Input file. STDIN if unspecified.\n" \
"-x --xpass <passwd> Provide password. INSECURE! Use for testing\n" \
" or debugging only!\n" \
"-X --password-file <file> Read passphrase from <file>.\n" \
" --extpass <program> Use external program for password prompt.\n" \
"-i --keyid <id> Specify a key id for various operations.\n" \
"-r --recipient <string> Specify a recpipient, multiple allowed.\n" \
"-t --text Print textual representation of ojects.\n" \
@@ -51,7 +54,8 @@
"-a --armor --textmode same as -z\n" \
"\n" \
"Misc Options:\n" \
"-C --checksum [<key>] calculate a Blake2 checksum of one or more files.\n" \
"-C --checksum calculate a Blake2 checksum of one or more files.\n" \
" add -x <key> to compute an authenticated hash.\n" \
"\n" \
"Arguments:\n" \
"Extra arguments after options are treated as filenames or\n" \

View File

@@ -14,7 +14,10 @@ General Options:
-V --vault <vaultfile> Specify an alternate vault file.
-O --outfile <file> Output file. STDOUT if unspecified.
-I --infile <file> Input file. STDIN if unspecified.
-x --xpass <passwd> Provide password. INSECURE! Use for testing
or debugging only!
-X --password-file <file> Read passphrase from <file>.
--extpass <program> Use external program for password prompt.
-i --keyid <id> Specify a key id for various operations.
-r --recipient <string> Specify a recpipient, multiple allowed.
-t --text Print textual representation of ojects.
@@ -49,7 +52,8 @@ Encoding Options:
-a --armor --textmode same as -z
Misc Options:
-C --checksum [<key>] calculate a Blake2 checksum of one or more files.
-C --checksum calculate a Blake2 checksum of one or more files.
add -x <key> to compute an authenticated hash.
Arguments:
Extra arguments after options are treated as filenames or

View File

@@ -19,26 +19,25 @@
You can contact me by mail: <tlinden AT cpan DOT org>.
*/
#include "z85util.h"
int pcpz85_encode(char *infile, char *outfile) {
FILE *in;
FILE *out;
if(infile == NULL)
if (infile == NULL)
in = stdin;
else {
if((in = fopen(infile, "rb")) == NULL) {
if ((in = fopen(infile, "rb")) == NULL) {
fatal(ptx, "Could not open input file %s\n", infile);
goto errz1;
}
}
if(outfile == NULL)
if (outfile == NULL)
out = stdout;
else {
if((out = fopen(outfile, "wb+")) == NULL) {
if ((out = fopen(outfile, "wb+")) == NULL) {
fatal(ptx, "Could not open output file %s\n", outfile);
goto errz1;
}
@@ -47,18 +46,18 @@ int pcpz85_encode(char *infile, char *outfile) {
byte *input = NULL;
size_t inputBufSize = 0;
byte onebyte[1];
while(!feof(in)) {
if(!fread(&onebyte, 1, 1, in))
while (!feof(in)) {
if (!fread(&onebyte, 1, 1, in))
break;
byte *tmp = realloc(input, inputBufSize + 1);
input = tmp;
memmove(&input[inputBufSize], onebyte, 1);
inputBufSize ++;
inputBufSize++;
}
fclose(in);
if(inputBufSize == 0) {
if (inputBufSize == 0) {
fatal(ptx, "Input file is empty!\n");
goto errz2;
}
@@ -66,9 +65,9 @@ int pcpz85_encode(char *infile, char *outfile) {
size_t zlen;
char *encoded = pcp_z85_encode(input, inputBufSize, &zlen, 1);
if(encoded != NULL) {
if (encoded != NULL) {
fprintf(out, "%s\n%s\n%s\n", PCP_ZFILE_HEADER, encoded, PCP_ZFILE_FOOTER);
if(ferror(out) != 0) {
if (ferror(out) != 0) {
fatal(ptx, "Failed to write z85 output!\n");
}
free(encoded);
@@ -77,33 +76,30 @@ int pcpz85_encode(char *infile, char *outfile) {
return 0;
errz2:
errz2:
free(input);
errz1:
errz1:
return 1;
}
int pcpz85_decode(char *infile, char *outfile) {
FILE *in;
FILE *out;
if(infile == NULL)
if (infile == NULL)
in = stdin;
else {
if((in = fopen(infile, "rb")) == NULL) {
if ((in = fopen(infile, "rb")) == NULL) {
fatal(ptx, "Could not open input file %s\n", infile);
goto errdz1;
}
}
if(outfile == NULL)
if (outfile == NULL)
out = stdout;
else {
if((out = fopen(outfile, "wb+")) == NULL) {
if ((out = fopen(outfile, "wb+")) == NULL) {
fatal(ptx, "Could not open output file %s\n", outfile);
goto errdz1;
}
@@ -111,20 +107,17 @@ int pcpz85_decode(char *infile, char *outfile) {
char *encoded = pcp_readz85file(ptx, in);
if(encoded == NULL)
if (encoded == NULL)
goto errdz1;
size_t clen;
byte *decoded = pcp_z85_decode(ptx, encoded, &clen);
if(decoded == NULL)
if (decoded == NULL)
goto errdz2;
fwrite(decoded, clen, 1, out);
fclose(out);
if(ferror(out) != 0) {
if (fclose(out) != 0) {
fatal(ptx, "Failed to write decoded output!\n");
goto errdz3;
}
@@ -133,12 +126,12 @@ int pcpz85_decode(char *infile, char *outfile) {
free(decoded);
return 0;
errdz3:
errdz3:
free(decoded);
errdz2:
errdz2:
free(encoded);
errdz1:
errdz1:
return 1;
}

View File

@@ -28,7 +28,7 @@ if BUILDJSON
MAYJSON=jsontest
endif
AM_CFLAGS = -I../include/pcp -I../src -I../libpcp/scrypt/crypto
AM_CFLAGS = -I../include/pcp -I../src
check_PROGRAMS = invalidkeys gencheader statictest $(CPPTEST) \
buffertest sample streamtest pipetest decodertest mangle
@@ -68,7 +68,7 @@ mangle_LDADD =
mangle_SOURCES = mangle.c
invalidkeys_LDADD = ../libpcp/.libs/libpcp1.a \
../src/keyprint.o ../src/keymgmt.o ../src/readpass.o
../src/keyprint.o ../src/keymgmt.o
invalidkeys_SOURCES = invalidkeys.c
if BUILDCPP
@@ -94,21 +94,21 @@ test: check ctest $(MAYPY) $(MAYCPP) $(MAYJSON)
ctest:
rm -f test* v* stresstest/*
./unittests.pl unittests.cfg $(CHECK)
./unittests.sh unittests.cfg $(CHECK)
@echo "To run a single test only, type: 'make test CHECK=testname'"
pytest:
./unittests.pl pyunittests.cfg $(CHECK)
./unittests.sh pyunittests.cfg $(CHECK)
docpptest:
./unittests.pl cppunittests.cfg $(CHECK)
./unittests.sh cppunittests.cfg $(CHECK)
jsontest:
./unittests.pl jsonunittests.cfg $(CHECK)
./unittests.sh jsonunittests.cfg $(CHECK)
stresstest: check
./unittests.pl stresstests.cfg
./unittests.sh stresstests.cfg
iotest: check
./unittests.pl iotests.cfg
./unittests.sh iotests.cfg
sudo umount -f env

View File

@@ -1,9 +1,9 @@
----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----
1][S6097-%&#]c=V(%sWNt}-r6LMx$@@an<T6mz>3&K8{65fN}tfPsN+9oKbfm9/=PXA{S^
la=*sAv38NRiJO0aJS4rmx?mypA$TROMAp>vnWxqulxBM?Zyz@u[Noobvdm/Jwj%bo^9)00
0080SSi2097-%&@x5V2M>5b0037krBV1e00&(h000125(&Aw000Gy00SAaB7GxavqGsKG}e
hz01xRx1POWzCwZ#jlsB[R0000i6Awmo3t<i=y*{*[Bu<UXv{%fN0003s0dgX9k.t1Y4]E.
wJqps<VO=l+TY?Cn*FU72QK@@o*Qy]-cSK>[B}O^{C#D)!/>X^8XOnk&j2YmXVJ.{X2bXp[
YQ(E[Fgaa2UFf>x&j1=9e.nNOhhE13iI2CiHS=PRD.0YP2c$wabl3.ATFlqe8Zriz*trfz8
+%^.mf0q/ek(&S
1][S609x+qRxIc%9DnX1G9dD]Jg]@^u9pUFfzF>xqfpgkuQ}++S$?MWJTUdh(q+bJ>M3a9A
7Px8mj54K:64SP+]cM6&/GjCnK8m/eFPwybe:L=}co-}W>sKdCquHXZPlmg{5$Esbo^9)00
0080SSi209x+qRt{O@2M>5b003f>KTp5d00&(h00014[r23$000Gy00SAaB7GxavqLB5nRc
{x01xRx1POWzCwZ#jlsB[R0000i6Awmo3t<i=y*{*[Bu<UXv{%fN0003s0c)0/=73jW2XhD
:x71TdA*:km]lgxS/]u()mP[i%sbr90kLxIiD%hmTRPQXwVn+E-(Zu6MHkO+hfoC$i3aG=:
uP)YsgY/hv/{HE*w)Qsh0r=j-WLGtZrQZ+[}Ih#c}>>&iM!Wk=*K^mMI4ZBtM^MBnIM^uU9
k.ZF6951jUlqJv
----- END ED25519-CURVE29915 PUBLIC KEY -----

View File

@@ -65,10 +65,10 @@ void test0() {
DECRYPTED = _openrd("testcppdecrypted", CA);
char *got = (char *)ucmalloc(10);
if(fread(got, 1, 6, DECRYPTED) < 6) {
throw pcp::exception(CA, "read error, could not read decrypted content");
throw pcp::exception(CA, "read error, could not read decrypted content");
}
if(strncmp(got, "HALLO", 5) != 0) {
throw pcp::exception(CA);
throw pcp::exception(CA);
}
free(got);
}
@@ -173,7 +173,6 @@ void test4() {
}
int main(int argc, char **argv) {
sodium_init();
PcpContext *ptx = new PcpContext();
try {

View File

@@ -1,26 +1,37 @@
# -*-sh-*-
#
# test the c++ api
<test check-cpp-crypto>
cmd = ./cpptest 0
expect = /ok/
</test>
<test check-cpp-vault>
cmd = ./cpptest 1
expect = /ok/
</test>
check_cpp_crypto () {
cmd="./cpptest 0"
expect=/ok/
check "$cmd" "$expect" "$input"
}
<test check-cpp-import-pub>
cmd = ./cpptest 2
expect = /ok/
</test>
check_cpp_vault () {
cmd="./cpptest 1"
expect=/ok/
check "$cmd" "$expect" "$input"
}
<test check-cpp-signature>
cmd = ./cpptest 3
expect = /ok/
</test>
check_cpp_import_pub () {
cmd="./cpptest 2"
expect=/ok/
check "$cmd" "$expect" "$input"
}
<test check-buffer>
cmd = ./cpptest 4
expect = /ok/
</test>
check_cpp_signature () {
cmd="./cpptest 3"
expect=/ok/
check "$cmd" "$expect" "$input"
}
check_buffer () {
cmd="./cpptest 4"
expect=/ok/
check "$cmd" "$expect" "$input"
}
prepare () {
:
}

View File

@@ -118,22 +118,22 @@ int main(int argc, char **argv) {
back = pcp_z85_decode(ptx, raw, &zlen);
if(back == NULL) {
if(mode > 3) {
/* expected fail */
ret = TRUE;
/* expected fail */
ret = TRUE;
}
else {
/* expected ok */
ret = FALSE;
/* expected ok */
ret = FALSE;
}
}
else {
if(mode > 3) {
/* expected fail */
ret = FALSE;
/* expected fail */
ret = FALSE;
}
else {
/* expected ok */
ret = TRUE;
/* expected ok */
ret = TRUE;
}
}
}
@@ -143,7 +143,7 @@ int main(int argc, char **argv) {
if(mode <= 3 && memcmp(back, clear, 256) != 0) {
ret = FALSE;
if(ptx->pcp_errset == 0) {
fatal(ptx, "decoded content doesn't match\n");
fatal(ptx, "decoded content doesn't match\n");
}
}
}

View File

@@ -12,7 +12,7 @@ void pr(char *var, unsigned char *d, size_t len) {
}
int main() {
sodium_init();
if(sodium_init() == -1) return 1;
pcp_key_t *a = pcpkey_new();
pcp_key_t *b = pcpkey_new();

View File

@@ -12,7 +12,7 @@ gen() {
pub=$5
sec=$6
(echo $owner; echo $mail) | $pcp -V vxxx$owner -k -x $pass > /dev/null 2>&1
(echo $owner; echo $mail; echo yes) | $pcp -V vxxx$owner -k -x $pass > /dev/null 2>&1
id=`$pcp -V vxxx$owner -l | grep $owner | awk '{print $1}'`
@@ -41,14 +41,14 @@ ser=`$pcp -V vxxxBart -t -i $ids | grep Serial | awk '{print $3}'`
gen Niemand niemand@local n y unknown1 unknown2
$pcp1 -V unknown3 -l
echo hallo | $pcp -e -x a -z | egrep -v "^ " | egrep -v -- "----" | grep . > unknown4
echo blah | $pcp -g -x a | egrep -v "^ " | egrep -v -- "----" | grep . > unknown5
echo blah | $pcp -V vxxxBart -g -x a | egrep -v "^ " | egrep -v -- "----" | grep . > unknown5
echo "bartid = $ids
bartserial = $ser
idbobby = $idb
idalicia = $ida
mailbobby = bobby@local
mailalicia = alicia@local" > keys.cfg
echo "bartid=$ids
bartserial=$ser
idbobby=$idb
idalicia=$ida
mailbobby=bobby@local
mailalicia=alicia@local" > keys.cfg
./gencheader > static.h

View File

@@ -10,7 +10,7 @@ int main() {
strcpy(o, "xxxx");
strcpy(m, "xxxx");
sodium_init();
if(sodium_init() == -1) return 1;
PCPCTX *ptx = ptx_new();
pcp_key_t *k = pcpkey_new ();

Some files were not shown because too many files have changed in this diff Show More