metadata.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * \file metadata.c
  3. * \brief Certificate Metadata Probe.
  4. *
  5. */
  6. #include <string.h>
  7. #include <openssl/pem.h>
  8. #include <openssl/rsa.h>
  9. #include <openssl/x509.h>
  10. #include "qa/questions/questions.h"
  11. #include "qa/questions/qstrings.h"
  12. /* taken from openssl's s_client app source */
  13. #define BUFSIZE 1024*8
  14. /* for some reasons this is commented into openssl's source code x509.h */
  15. #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber)
  16. #define ISSUER "issuer"
  17. #define SUBJECT "subject"
  18. #define SERIAL "serial"
  19. #define BITLEN "bitlen"
  20. #define PKEY "public key"
  21. #define NBITLEN "N bits"
  22. #define EBITLEN "e bits"
  23. #define MODULUS "modulus"
  24. #define E "pub exp"
  25. #define NOTBEF "not before"
  26. #define NOTAFT "not after"
  27. static BIO* out;
  28. static int
  29. metadata_question_setup(void)
  30. {
  31. out = BIO_new_fp(stdout, BIO_NOCLOSE);
  32. return (out != NULL);
  33. }
  34. static int
  35. metadata_question_teardown(void)
  36. {
  37. return BIO_free(out);
  38. }
  39. static int
  40. metadata_question_ask_crt(X509* crt)
  41. {
  42. EVP_PKEY* pkey = NULL;
  43. BIGNUM *serial = NULL;
  44. char *sserial = NULL;
  45. char sbuf[BUFSIZE];
  46. char ibuf[BUFSIZE];
  47. char not_after[64], not_before[64];
  48. /* subject informations: country, organization, common name */
  49. X509_NAME_oneline(X509_get_subject_name(crt), sbuf, sizeof(sbuf));
  50. /* issuer informations: country, organization, common name */
  51. X509_NAME_oneline(X509_get_issuer_name(crt), ibuf, sizeof(ibuf));
  52. /* serial number */
  53. serial = ASN1_INTEGER_to_BN(X509_get_serialNumber(crt), NULL);
  54. sserial = BN_bn2hex(serial);
  55. /* time fields */
  56. ASN1_TIME_str(not_before, X509_get_notBefore(crt));
  57. ASN1_TIME_str(not_after, X509_get_notAfter(crt));
  58. /* public key */
  59. pkey = X509_get_pubkey(crt);
  60. /* BIO_printf(out, "%-10s\n", PKEY); */
  61. /* PEM_write_bio_RSAPublicKey(out, pkey->pkey.rsa); */
  62. /* BIO_printf(out, "\r\n\r\n"); */
  63. /* public key bitlength */
  64. BIO_printf(out,
  65. "%-10s:%s\n"
  66. "%-10s:%s\n"
  67. "%-10s:%s\n"
  68. "%-10s:%s\n"
  69. "%-10s:%s\n"
  70. "%-10s:%d\n",
  71. SUBJECT, sbuf,
  72. ISSUER, ibuf,
  73. SERIAL, sserial,
  74. NOTBEF, not_before,
  75. NOTAFT, not_after,
  76. BITLEN, EVP_PKEY_bits(pkey));
  77. /* XXX. Compression. TLS version.
  78. * This needs access to the socket.
  79. * Therefore a design change has to be taken. :( */
  80. /* Note: debian builds withouth sslv2 support
  81. * <https://lists.debian.org/debian-devel/2011/04/msg00049.html> */
  82. /* brands and trivial sanity check for defaults */
  83. if (strstr(sbuf, "localhost") ||
  84. strstr(sbuf, "none") ||
  85. strstr(sbuf, "test"))
  86. fprintf(stderr,
  87. "The certificate contains dummy informations.\n");
  88. OPENSSL_free(sserial);
  89. BN_free(serial);
  90. EVP_PKEY_free(pkey);
  91. return 0;
  92. }
  93. RSA *metadata_question_ask_rsa(const RSA* rsa)
  94. {
  95. char *s, *t;
  96. s = BN_bn2hex(rsa->e);
  97. t = BN_bn2hex(rsa->n);
  98. BIO_printf(out,
  99. "%-10s:%s\n"
  100. "%-10s:%s\n"
  101. "%-10s:%d\n"
  102. "%-10s:%d\n",
  103. MODULUS, t,
  104. E, s,
  105. EBITLEN, BN_num_bits(rsa->e),
  106. NBITLEN, BN_num_bits(rsa->n));
  107. if (BN_num_bits(rsa->n) < 2048)
  108. fprintf(stdout,
  109. "RSA keys < 2048 are disallowed after 2013.\n"
  110. "For more informations, see "
  111. "<http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf>\n");
  112. OPENSSL_free(s);
  113. OPENSSL_free(t);
  114. return NULL;
  115. }
  116. qa_question_t MetadataQuestion = {
  117. .name = "metadata",
  118. .pretty_name = "Metadata",
  119. .setup = metadata_question_setup,
  120. .teardown = metadata_question_teardown,
  121. .ask_crt = metadata_question_ask_crt,
  122. .ask_rsa = metadata_question_ask_rsa
  123. };