1 #include <Rinternals.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <openssl/crypto.h>
5 #include <openssl/pem.h>
6 #include "utils.h"
7 #include "compatibility.h"
8
R_parse_der_pubkey(SEXP input)9 SEXP R_parse_der_pubkey(SEXP input){
10 const unsigned char *ptr = RAW(input);
11 EVP_PKEY *pkey = d2i_PUBKEY(NULL, &ptr, LENGTH(input));
12 bail(!!pkey);
13 unsigned char *buf = NULL;
14 int len = i2d_PUBKEY(pkey, &buf);
15 EVP_PKEY_free(pkey);
16 bail(len);
17 SEXP res = allocVector(RAWSXP, len);
18 memcpy(RAW(res), buf, len);
19 OPENSSL_free(buf);
20 return res;
21 }
22
R_parse_der_key(SEXP input)23 SEXP R_parse_der_key(SEXP input){
24 BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
25 EVP_PKEY *pkey = d2i_PrivateKey_bio(mem, NULL);
26 BIO_free(mem);
27 bail(!!pkey);
28 unsigned char *buf = NULL;
29 int len = i2d_PrivateKey(pkey, &buf);
30 EVP_PKEY_free(pkey);
31 bail(len);
32 SEXP res = allocVector(RAWSXP, len);
33 memcpy(RAW(res), buf, len);
34 OPENSSL_free(buf);
35 return res;
36 }
37
R_parse_der_cert(SEXP input)38 SEXP R_parse_der_cert(SEXP input){
39 const unsigned char *ptr = RAW(input);
40 X509 *cert = d2i_X509(NULL, &ptr, LENGTH(input));
41 bail(!!cert);
42 unsigned char *buf = NULL;
43 int len = i2d_X509(cert, &buf);
44 X509_free(cert);
45 bail(len);
46 SEXP res = allocVector(RAWSXP, len);
47 memcpy(RAW(res), buf, len);
48 OPENSSL_free(buf);
49 return res;
50 }
51
52 /* Convert private to public key */
R_derive_pubkey(SEXP input)53 SEXP R_derive_pubkey(SEXP input){
54 BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
55 EVP_PKEY *pkey = d2i_PrivateKey_bio(mem, NULL);
56 BIO_free(mem);
57 bail(!!pkey);
58 unsigned char *buf = NULL;
59 int len = i2d_PUBKEY(pkey, &buf);
60 EVP_PKEY_free(pkey);
61 bail(len);
62 SEXP res = allocVector(RAWSXP, len);
63 memcpy(RAW(res), buf, len);
64 OPENSSL_free(buf);
65 return res;
66 }
67
68 /* Convert cert to public key */
R_cert_pubkey(SEXP input)69 SEXP R_cert_pubkey(SEXP input){
70 const unsigned char *ptr = RAW(input);
71 X509 *cert = d2i_X509(NULL, &ptr, LENGTH(input));
72 bail(!!cert);
73 EVP_PKEY *key = X509_get_pubkey(cert);
74 X509_free(cert);
75 bail(!!key);
76 unsigned char *buf = NULL;
77 int len = i2d_PUBKEY(key, &buf);
78 EVP_PKEY_free(key);
79 bail(len);
80 SEXP res = allocVector(RAWSXP, len);
81 memcpy(RAW(res), buf, len);
82 OPENSSL_free(buf);
83 return res;
84 }
85
R_pubkey_type(SEXP input)86 SEXP R_pubkey_type(SEXP input){
87 BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
88 EVP_PKEY *pkey = d2i_PUBKEY_bio(mem, NULL);
89 BIO_free(mem);
90 if(!pkey)
91 return R_NilValue;
92 const char *keytype;
93 switch(EVP_PKEY_base_id(pkey)){
94 case EVP_PKEY_RSA:
95 keytype = "rsa";
96 break;
97 case EVP_PKEY_DSA:
98 keytype = "dsa";
99 break;
100 case EVP_PKEY_EC:
101 keytype = "ecdsa";
102 break;
103 #ifdef EVP_PKEY_ED25519
104 case EVP_PKEY_X25519:
105 keytype = "x25519";
106 break;
107 case EVP_PKEY_ED25519:
108 keytype = "ed25519";
109 break;
110 #endif
111 default:
112 Rf_error("Unsupported key type: %d", EVP_PKEY_base_id(pkey));
113 }
114 EVP_PKEY_free(pkey);
115 return mkString(keytype);
116 }
117
ec_bitsize(int nid)118 int ec_bitsize(int nid){
119 switch(nid){
120 case NID_X9_62_prime256v1:
121 return 256;
122 case NID_secp384r1:
123 return 384;
124 case NID_secp521r1:
125 return 521;
126 }
127 return 0;
128 }
129
R_pubkey_bitsize(SEXP input)130 SEXP R_pubkey_bitsize(SEXP input){
131 BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
132 EVP_PKEY *pkey = d2i_PUBKEY_bio(mem, NULL);
133 BIO_free(mem);
134 if(!pkey)
135 return R_NilValue;
136 int size = 0;
137 const BIGNUM * val;
138 switch(EVP_PKEY_base_id(pkey)){
139 case EVP_PKEY_RSA:
140 MY_RSA_get0_key(EVP_PKEY_get1_RSA(pkey), &val, NULL, NULL);
141 size = BN_num_bits(val);
142 break;
143 case EVP_PKEY_DSA:
144 MY_DSA_get0_pqg(EVP_PKEY_get1_DSA(pkey), &val, NULL, NULL);
145 size = BN_num_bits(val);
146 break;
147 #ifdef EVP_PKEY_ED25519
148 case EVP_PKEY_ED25519:
149 case EVP_PKEY_X25519:
150 size = 256;
151 break;
152 #endif
153 #ifndef OPENSSL_NO_EC
154 case EVP_PKEY_EC:
155 size = ec_bitsize(EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get1_EC_KEY(pkey))));
156 break;
157 #endif //OPENSSL_NO_EC
158 default:
159 Rf_error("Unsupported key type: %d", EVP_PKEY_base_id(pkey));
160 }
161 EVP_PKEY_free(pkey);
162 return ScalarInteger(size);
163 }
164