ct_b64.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <limits.h>
  10. #include <string.h>
  11. #include <openssl/ct.h>
  12. #include <openssl/err.h>
  13. #include <openssl/evp.h>
  14. #include "ct_local.h"
  15. /*
  16. * Decodes the base64 string |in| into |out|.
  17. * A new string will be malloc'd and assigned to |out|. This will be owned by
  18. * the caller. Do not provide a pre-allocated string in |out|.
  19. */
  20. static int ct_base64_decode(const char *in, unsigned char **out)
  21. {
  22. size_t inlen = strlen(in);
  23. int outlen, i;
  24. unsigned char *outbuf = NULL;
  25. if (inlen == 0) {
  26. *out = NULL;
  27. return 0;
  28. }
  29. outlen = (inlen / 4) * 3;
  30. outbuf = OPENSSL_malloc(outlen);
  31. if (outbuf == NULL)
  32. goto err;
  33. outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen);
  34. if (outlen < 0) {
  35. ERR_raise(ERR_LIB_CT, CT_R_BASE64_DECODE_ERROR);
  36. goto err;
  37. }
  38. /* Subtract padding bytes from |outlen|. Any more than 2 is malformed. */
  39. i = 0;
  40. while (in[--inlen] == '=') {
  41. --outlen;
  42. if (++i > 2)
  43. goto err;
  44. }
  45. *out = outbuf;
  46. return outlen;
  47. err:
  48. OPENSSL_free(outbuf);
  49. return -1;
  50. }
  51. SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
  52. ct_log_entry_type_t entry_type, uint64_t timestamp,
  53. const char *extensions_base64,
  54. const char *signature_base64)
  55. {
  56. SCT *sct = SCT_new();
  57. unsigned char *dec = NULL;
  58. const unsigned char* p = NULL;
  59. int declen;
  60. if (sct == NULL) {
  61. ERR_raise(ERR_LIB_CT, ERR_R_CT_LIB);
  62. return NULL;
  63. }
  64. /*
  65. * RFC6962 section 4.1 says we "MUST NOT expect this to be 0", but we
  66. * can only construct SCT versions that have been defined.
  67. */
  68. if (!SCT_set_version(sct, version)) {
  69. ERR_raise(ERR_LIB_CT, CT_R_SCT_UNSUPPORTED_VERSION);
  70. goto err;
  71. }
  72. declen = ct_base64_decode(logid_base64, &dec);
  73. if (declen < 0) {
  74. ERR_raise(ERR_LIB_CT, X509_R_BASE64_DECODE_ERROR);
  75. goto err;
  76. }
  77. if (!SCT_set0_log_id(sct, dec, declen))
  78. goto err;
  79. dec = NULL;
  80. declen = ct_base64_decode(extensions_base64, &dec);
  81. if (declen < 0) {
  82. ERR_raise(ERR_LIB_CT, X509_R_BASE64_DECODE_ERROR);
  83. goto err;
  84. }
  85. SCT_set0_extensions(sct, dec, declen);
  86. dec = NULL;
  87. declen = ct_base64_decode(signature_base64, &dec);
  88. if (declen < 0) {
  89. ERR_raise(ERR_LIB_CT, X509_R_BASE64_DECODE_ERROR);
  90. goto err;
  91. }
  92. p = dec;
  93. if (o2i_SCT_signature(sct, &p, declen) <= 0)
  94. goto err;
  95. OPENSSL_free(dec);
  96. dec = NULL;
  97. SCT_set_timestamp(sct, timestamp);
  98. if (!SCT_set_log_entry_type(sct, entry_type))
  99. goto err;
  100. return sct;
  101. err:
  102. OPENSSL_free(dec);
  103. SCT_free(sct);
  104. return NULL;
  105. }
  106. /*
  107. * Allocate, build and returns a new |ct_log| from input |pkey_base64|
  108. * It returns 1 on success,
  109. * 0 on decoding failure, or invalid parameter if any
  110. * -1 on internal (malloc) failure
  111. */
  112. int CTLOG_new_from_base64_ex(CTLOG **ct_log, const char *pkey_base64,
  113. const char *name, OSSL_LIB_CTX *libctx,
  114. const char *propq)
  115. {
  116. unsigned char *pkey_der = NULL;
  117. int pkey_der_len;
  118. const unsigned char *p;
  119. EVP_PKEY *pkey = NULL;
  120. if (ct_log == NULL) {
  121. ERR_raise(ERR_LIB_CT, ERR_R_PASSED_INVALID_ARGUMENT);
  122. return 0;
  123. }
  124. pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der);
  125. if (pkey_der_len < 0) {
  126. ERR_raise(ERR_LIB_CT, CT_R_LOG_CONF_INVALID_KEY);
  127. return 0;
  128. }
  129. p = pkey_der;
  130. pkey = d2i_PUBKEY_ex(NULL, &p, pkey_der_len, libctx, propq);
  131. OPENSSL_free(pkey_der);
  132. if (pkey == NULL) {
  133. ERR_raise(ERR_LIB_CT, CT_R_LOG_CONF_INVALID_KEY);
  134. return 0;
  135. }
  136. *ct_log = CTLOG_new_ex(pkey, name, libctx, propq);
  137. if (*ct_log == NULL) {
  138. EVP_PKEY_free(pkey);
  139. return 0;
  140. }
  141. return 1;
  142. }
  143. int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64,
  144. const char *name)
  145. {
  146. return CTLOG_new_from_base64_ex(ct_log, pkey_base64, name, NULL, NULL);
  147. }