Tor  0.4.7.0-alpha-dev
signing.c
Go to the documentation of this file.
1 /* Copyright (c) 2001 Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
7 /**
8  * \file signing.c
9  * \brief Code to sign directory objects.
10  **/
11 
12 #include "core/or/or.h"
14 
15 /** Helper: used to generate signatures for routers, directories and
16  * network-status objects. Given a <b>digest_len</b>-byte digest in
17  * <b>digest</b> and a secret <b>private_key</b>, generate an PKCS1-padded
18  * signature, BASE64-encode it, surround it with -----BEGIN/END----- pairs,
19  * and return the new signature on success or NULL on failure.
20  */
21 char *
22 router_get_dirobj_signature(const char *digest,
23  size_t digest_len,
24  const crypto_pk_t *private_key)
25 {
26  char *signature;
27  size_t i, keysize;
28  int siglen;
29  char *buf = NULL;
30  size_t buf_len;
31  /* overestimate of BEGIN/END lines total len. */
32 #define BEGIN_END_OVERHEAD_LEN 64
33 
34  keysize = crypto_pk_keysize(private_key);
35  signature = tor_malloc(keysize);
36  siglen = crypto_pk_private_sign(private_key, signature, keysize,
37  digest, digest_len);
38  if (siglen < 0) {
39  log_warn(LD_BUG,"Couldn't sign digest.");
40  goto err;
41  }
42 
43  /* The *2 here is a ridiculous overestimate of base-64 overhead. */
44  buf_len = (siglen * 2) + BEGIN_END_OVERHEAD_LEN;
45  buf = tor_malloc(buf_len);
46 
47  if (strlcpy(buf, "-----BEGIN SIGNATURE-----\n", buf_len) >= buf_len)
48  goto truncated;
49 
50  i = strlen(buf);
51  if (base64_encode(buf+i, buf_len-i, signature, siglen,
52  BASE64_ENCODE_MULTILINE) < 0) {
53  log_warn(LD_BUG,"couldn't base64-encode signature");
54  goto err;
55  }
56 
57  if (strlcat(buf, "-----END SIGNATURE-----\n", buf_len) >= buf_len)
58  goto truncated;
59 
60  tor_free(signature);
61  return buf;
62 
63  truncated:
64  log_warn(LD_BUG,"tried to exceed string length.");
65  err:
66  tor_free(signature);
67  tor_free(buf);
68  return NULL;
69 }
70 
71 /** Helper: used to generate signatures for routers, directories and
72  * network-status objects. Given a digest in <b>digest</b> and a secret
73  * <b>private_key</b>, generate a PKCS1-padded signature, BASE64-encode it,
74  * surround it with -----BEGIN/END----- pairs, and write it to the
75  * <b>buf_len</b>-byte buffer at <b>buf</b>. Return 0 on success, -1 on
76  * failure.
77  */
78 int
79 router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest,
80  size_t digest_len, crypto_pk_t *private_key)
81 {
82  size_t sig_len, s_len;
83  char *sig = router_get_dirobj_signature(digest, digest_len, private_key);
84  if (!sig) {
85  log_warn(LD_BUG, "No signature generated");
86  return -1;
87  }
88  sig_len = strlen(sig);
89  s_len = strlen(buf);
90  if (sig_len + s_len + 1 > buf_len) {
91  log_warn(LD_BUG, "Not enough room for signature");
92  tor_free(sig);
93  return -1;
94  }
95  memcpy(buf+s_len, sig, sig_len+1);
96  tor_free(sig);
97  return 0;
98 }
int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen, int flags)
Definition: binascii.c:215
size_t crypto_pk_keysize(const crypto_pk_t *env)
int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
#define LD_BUG
Definition: log.h:86
#define tor_free(p)
Definition: malloc.h:52
Master header file for Tor-specific functionality.
int router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest, size_t digest_len, crypto_pk_t *private_key)
Definition: signing.c:79
char * router_get_dirobj_signature(const char *digest, size_t digest_len, const crypto_pk_t *private_key)
Definition: signing.c:22
Header file for signing.c.