Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F27224604
sexp-secret.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
3 KB
Subscribers
None
sexp-secret.c
View Options
/* sexp-secret.c - SEXP handling of the secret key
* Copyright (C) 2020 g10 Code GmbH.
*
* This file is part of GnuPG.
*
* GnuPG 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.
*
* GnuPG 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 <https://www.gnu.org/licenses/>.
*/
#include
<config.h>
#include
"agent.h"
#include
"../common/sexp-parse.h"
/*
* When it's for ECC, fixup private key part in the cannonical SEXP
* representation in BUF. If not ECC, do nothing.
*/
gpg_error_t
fixup_when_ecc_private_key
(
unsigned
char
*
buf
,
size_t
*
buflen_p
)
{
const
unsigned
char
*
s
;
char
curve_name
[
256
]
=
{
0
,
};
size_t
n
;
size_t
buflen
=
*
buflen_p
;
s
=
buf
;
if
(
*
s
!=
'('
)
return
gpg_error
(
GPG_ERR_INV_SEXP
);
s
++
;
n
=
snext
(
&
s
);
if
(
!
n
)
return
gpg_error
(
GPG_ERR_INV_SEXP
);
if
(
smatch
(
&
s
,
n
,
"shadowed-private-key"
))
return
0
;
/* Nothing to do. */
if
(
!
smatch
(
&
s
,
n
,
"private-key"
))
return
gpg_error
(
GPG_ERR_UNKNOWN_SEXP
);
if
(
*
s
!=
'('
)
return
gpg_error
(
GPG_ERR_UNKNOWN_SEXP
);
s
++
;
n
=
snext
(
&
s
);
if
(
!
smatch
(
&
s
,
n
,
"ecc"
))
return
0
;
/* It's ECC */
while
(
*
s
==
'('
)
{
s
++
;
n
=
snext
(
&
s
);
if
(
!
n
)
return
gpg_error
(
GPG_ERR_INV_SEXP
);
if
(
n
==
5
&&
!
memcmp
(
s
,
"curve"
,
5
))
{
s
+=
n
;
n
=
snext
(
&
s
);
if
(
!
n
||
n
>=
sizeof
curve_name
)
return
gpg_error
(
GPG_ERR_INV_SEXP
);
memcpy
(
curve_name
,
s
,
n
);
curve_name
[
n
]
=
0
;
s
+=
n
;
}
else
if
(
n
==
1
&&
*
s
==
'd'
)
{
unsigned
char
*
s0
;
size_t
n0
;
s
+=
n
;
s0
=
(
unsigned
char
*
)
s
;
n
=
snext
(
&
s
);
n0
=
s
-
s0
;
if
(
!
n
)
return
gpg_error
(
GPG_ERR_INV_SEXP
);
else
if
(
!*
s
/* Leading 0x00 added at the front for classic curve */
&&
strcmp
(
curve_name
,
"Ed25519"
)
&&
strcmp
(
curve_name
,
"Ed448"
)
&&
strcmp
(
curve_name
,
"X448"
))
{
size_t
numsize
;
n
--
;
buflen
--
;
numsize
=
snprintf
(
s0
,
s
-
s0
+
1
,
"%u:"
,
(
unsigned
int
)
n
);
memmove
(
s0
+
numsize
,
s
+
1
,
buflen
-
(
s
-
buf
));
memset
(
s0
+
numsize
+
buflen
-
(
s
-
buf
),
0
,
(
n0
-
numsize
)
+
1
);
buflen
-=
(
n0
-
numsize
);
s
=
s0
+
numsize
+
n
;
*
buflen_p
=
buflen
;
}
else
s
+=
n
;
}
else
{
s
+=
n
;
n
=
snext
(
&
s
);
if
(
!
n
)
return
gpg_error
(
GPG_ERR_INV_SEXP
);
s
+=
n
;
}
if
(
*
s
!=
')'
)
return
gpg_error
(
GPG_ERR_INV_SEXP
);
s
++
;
}
if
(
*
s
!=
')'
)
return
gpg_error
(
GPG_ERR_INV_SEXP
);
s
++
;
return
0
;
}
/*
* Scan BUF to get SEXP, put into RESULT. Error offset will be in the
* pointer at R_ERROFF. For ECC, the private part 'd' will be fixed
* up; That part may have 0x00 prefix of signed MPI encoding, which is
* incompatible to opaque MPI handling.
*/
gpg_error_t
sexp_sscan_private_key
(
gcry_sexp_t
*
result
,
size_t
*
r_erroff
,
unsigned
char
*
buf
)
{
gpg_error_t
err
;
size_t
buflen
,
buflen0
;
buflen
=
buflen0
=
gcry_sexp_canon_len
(
buf
,
0
,
NULL
,
NULL
);
err
=
fixup_when_ecc_private_key
(
buf
,
&
buflen
);
if
(
!
err
)
err
=
gcry_sexp_sscan
(
result
,
r_erroff
,
(
char
*
)
buf
,
buflen0
);
wipememory
(
buf
,
buflen0
);
return
err
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Mon, Aug 25, 11:05 PM (1 d, 11 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
cf/f5/ae2cf78895c02da1d29bfd997054
Attached To
rG GnuPG
Event Timeline
Log In to Comment