194 uint32_t sig_creation_time,
197 if (!out_sig)
return false;
201 LOG_W(
TAG,
"gpgCrossSign: own GPG key not available");
205 uint8_t pk_body[128];
206 const size_t pk_body_len = buildPubkeyBody(target, pk_body,
sizeof(pk_body));
207 if (pk_body_len == 0)
return false;
209 const size_t uid_len = strnlen(target.
user_id,
sizeof(target.
user_id));
213 uint8_t hashed_subs[8];
214 const size_t hashed_subs_len = buildSigSubpackets(
215 true,
nullptr, sig_creation_time, hashed_subs,
sizeof(hashed_subs));
220 uint8_t sig_data_header[6];
221 sig_data_header[0] = 0x04;
222 sig_data_header[1] = kSigTypeGenericCert;
223 sig_data_header[2] = sig_algo;
224 sig_data_header[3] = kHashAlgoSha256;
225 sig_data_header[4] = (hashed_subs_len >> 8) & 0xFF;
226 sig_data_header[5] = hashed_subs_len & 0xFF;
228 const size_t sig_data_total =
sizeof(sig_data_header) + hashed_subs_len;
229 const uint8_t trailer[6] = {
231 static_cast<uint8_t
>((sig_data_total >> 24) & 0xFF),
232 static_cast<uint8_t
>((sig_data_total >> 16) & 0xFF),
233 static_cast<uint8_t
>((sig_data_total >> 8) & 0xFF),
234 static_cast<uint8_t
>(sig_data_total & 0xFF),
241 mbedtls_sha256_context ctx;
242 mbedtls_sha256_init(&ctx);
243 mbedtls_sha256_starts(&ctx, 0);
245 const uint8_t pk_prefix[3] = {
247 static_cast<uint8_t
>((pk_body_len >> 8) & 0xFF),
248 static_cast<uint8_t
>(pk_body_len & 0xFF),
250 mbedtls_sha256_update(&ctx, pk_prefix,
sizeof(pk_prefix));
251 mbedtls_sha256_update(&ctx, pk_body, pk_body_len);
253 const uint8_t uid_prefix[5] = {
255 static_cast<uint8_t
>((uid_len >> 24) & 0xFF),
256 static_cast<uint8_t
>((uid_len >> 16) & 0xFF),
257 static_cast<uint8_t
>((uid_len >> 8) & 0xFF),
258 static_cast<uint8_t
>(uid_len & 0xFF),
260 mbedtls_sha256_update(&ctx, uid_prefix,
sizeof(uid_prefix));
261 mbedtls_sha256_update(&ctx,
reinterpret_cast<const uint8_t*
>(target.
user_id), uid_len);
263 mbedtls_sha256_update(&ctx, sig_data_header,
sizeof(sig_data_header));
264 mbedtls_sha256_update(&ctx, hashed_subs, hashed_subs_len);
265 mbedtls_sha256_update(&ctx, trailer,
sizeof(trailer));
268 mbedtls_sha256_finish(&ctx, hash);
269 mbedtls_sha256_free(&ctx);
272 if (!se)
return false;
279 return se->ecdsaSign(slot, hash,
sizeof(hash), out_sig, &sig_len)
284 char* out,
size_t out_size,
287 if (!out || !out_len || out_size < 256)
return false;
288 if (key.
sig_len != 64)
return false;
293 uint8_t self_fp_v4[20] = {0};
294 std::memcpy(self_fp_v4, self_status.
fingerprint, 20);
297 uint8_t pk_body[128];
298 const size_t pk_body_len = buildPubkeyBody(key, pk_body,
sizeof(pk_body));
299 if (pk_body_len == 0)
return false;
306 uint8_t hashed_subs[8];
307 const size_t hashed_subs_len = buildSigSubpackets(
true, self_fp_v4,
309 hashed_subs,
sizeof(hashed_subs));
310 uint8_t unhashed_subs[10];
311 const size_t unhashed_subs_len = buildSigSubpackets(
false, self_fp_v4,
313 unhashed_subs,
sizeof(unhashed_subs));
316 uint8_t sig_body[256];
317 size_t sig_body_off = 0;
318 sig_body[sig_body_off++] = 0x04;
319 sig_body[sig_body_off++] = kSigTypeGenericCert;
320 sig_body[sig_body_off++] = sig_algo;
321 sig_body[sig_body_off++] = kHashAlgoSha256;
322 sig_body[sig_body_off++] = (hashed_subs_len >> 8) & 0xFF;
323 sig_body[sig_body_off++] = hashed_subs_len & 0xFF;
324 std::memcpy(sig_body + sig_body_off, hashed_subs, hashed_subs_len);
325 sig_body_off += hashed_subs_len;
326 sig_body[sig_body_off++] = (unhashed_subs_len >> 8) & 0xFF;
327 sig_body[sig_body_off++] = unhashed_subs_len & 0xFF;
328 std::memcpy(sig_body + sig_body_off, unhashed_subs, unhashed_subs_len);
329 sig_body_off += unhashed_subs_len;
333 const uint8_t pk_prefix[3] = {
335 static_cast<uint8_t
>((pk_body_len >> 8) & 0xFF),
336 static_cast<uint8_t
>(pk_body_len & 0xFF),
338 const uint8_t uid_prefix[5] = {
340 static_cast<uint8_t
>((uid_len >> 24) & 0xFF),
341 static_cast<uint8_t
>((uid_len >> 16) & 0xFF),
342 static_cast<uint8_t
>((uid_len >> 8) & 0xFF),
343 static_cast<uint8_t
>(uid_len & 0xFF),
345 uint8_t sig_data_header[6] = {
346 0x04, kSigTypeGenericCert, sig_algo, kHashAlgoSha256,
347 static_cast<uint8_t
>((hashed_subs_len >> 8) & 0xFF),
348 static_cast<uint8_t
>(hashed_subs_len & 0xFF),
350 const size_t sig_data_total =
sizeof(sig_data_header) + hashed_subs_len;
351 const uint8_t trailer[6] = {
353 static_cast<uint8_t
>((sig_data_total >> 24) & 0xFF),
354 static_cast<uint8_t
>((sig_data_total >> 16) & 0xFF),
355 static_cast<uint8_t
>((sig_data_total >> 8) & 0xFF),
356 static_cast<uint8_t
>(sig_data_total & 0xFF),
359 mbedtls_sha256_context ctx;
360 mbedtls_sha256_init(&ctx);
361 mbedtls_sha256_starts(&ctx, 0);
362 mbedtls_sha256_update(&ctx, pk_prefix,
sizeof(pk_prefix));
363 mbedtls_sha256_update(&ctx, pk_body, pk_body_len);
364 mbedtls_sha256_update(&ctx, uid_prefix,
sizeof(uid_prefix));
365 mbedtls_sha256_update(&ctx,
reinterpret_cast<const uint8_t*
>(key.
user_id), uid_len);
366 mbedtls_sha256_update(&ctx, sig_data_header,
sizeof(sig_data_header));
367 mbedtls_sha256_update(&ctx, hashed_subs, hashed_subs_len);
368 mbedtls_sha256_update(&ctx, trailer,
sizeof(trailer));
370 mbedtls_sha256_finish(&ctx, hash);
371 mbedtls_sha256_free(&ctx);
373 sig_body[sig_body_off++] = hash[0];
374 sig_body[sig_body_off++] = hash[1];
379 sig_body + sig_body_off,
sizeof(sig_body) - sig_body_off);
380 if (mpi_off == 0)
return false;
381 sig_body_off += mpi_off;
383 sig_body + sig_body_off,
sizeof(sig_body) - sig_body_off);
384 if (mpi_off == 0)
return false;
385 sig_body_off += mpi_off;
388 uint8_t binary[1024];
389 size_t binary_off = 0;
392 binary[binary_off++] = 0xC6;
393 binary_off += writeNewFormatLength(binary + binary_off, pk_body_len);
394 std::memcpy(binary + binary_off, pk_body, pk_body_len);
395 binary_off += pk_body_len;
398 binary[binary_off++] = 0xCD;
399 binary_off += writeNewFormatLength(binary + binary_off, uid_len);
400 std::memcpy(binary + binary_off, key.
user_id, uid_len);
401 binary_off += uid_len;
404 binary[binary_off++] = 0xC2;
405 binary_off += writeNewFormatLength(binary + binary_off, sig_body_off);
406 std::memcpy(binary + binary_off, sig_body, sig_body_off);
407 binary_off += sig_body_off;
410 static constexpr const char* kBegin =
"-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\n";
411 static constexpr const char* kEnd =
"-----END PGP PUBLIC KEY BLOCK-----\r\n";
412 const size_t begin_len = std::strlen(kBegin);
413 const size_t end_len = std::strlen(kEnd);
415 if (begin_len + end_len + (binary_off * 2) + 16 > out_size)
return false;
418 std::memcpy(out + off, kBegin, begin_len);
421 size_t body_written = armorBase64(binary, binary_off, out + off, out_size - off);
422 if (body_written == 0)
return false;
426 uint8_t crc_bytes[3];
427 uint32_t crc = crc24(binary, binary_off);
428 crc_bytes[0] = (crc >> 16) & 0xFF;
429 crc_bytes[1] = (crc >> 8) & 0xFF;
430 crc_bytes[2] = crc & 0xFF;
432 if (off + 8 > out_size)
return false;
435 if (mbedtls_base64_encode(
reinterpret_cast<unsigned char*
>(out + off),
436 out_size - off, &crc_len,
437 crc_bytes,
sizeof(crc_bytes)) != 0) {
444 if (off + end_len > out_size)
return false;
445 std::memcpy(out + off, kEnd, end_len);
448 if (off < out_size) out[off] =
'\0';