nokogiri-xmlsec1 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +4 -0
  6. data/Guardfile +13 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +133 -0
  9. data/Rakefile +30 -0
  10. data/dependencies.yml +3 -0
  11. data/ext/nokogiri_ext_xmlsec/extconf.rb +489 -0
  12. data/ext/nokogiri_ext_xmlsec/init.c +46 -0
  13. data/ext/nokogiri_ext_xmlsec/nokogiri_decrypt_with_key.c +124 -0
  14. data/ext/nokogiri_ext_xmlsec/nokogiri_encrypt_with_key.c +182 -0
  15. data/ext/nokogiri_ext_xmlsec/nokogiri_helpers_set_attribute_id.c +43 -0
  16. data/ext/nokogiri_ext_xmlsec/nokogiri_init.c +32 -0
  17. data/ext/nokogiri_ext_xmlsec/nokogiri_sign_certificate.c +104 -0
  18. data/ext/nokogiri_ext_xmlsec/nokogiri_sign_rsa.c +95 -0
  19. data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_certificates.c +96 -0
  20. data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_named_keys.c +106 -0
  21. data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_rsa.c +56 -0
  22. data/ext/nokogiri_ext_xmlsec/shutdown.c +12 -0
  23. data/ext/nokogiri_ext_xmlsec/xmlsecrb.h +39 -0
  24. data/lib/nokogiri-xmlsec.rb +1 -0
  25. data/lib/xmlsec.rb +110 -0
  26. data/lib/xmlsec/version.rb +3 -0
  27. data/nokogiri-xmlsec1.gemspec +46 -0
  28. data/ports/patches/libxml2/0001-Fix-parser-local-buffers-size-problems.patch +265 -0
  29. data/ports/patches/libxml2/0002-Fix-entities-local-buffers-size-problems.patch +102 -0
  30. data/ports/patches/libxml2/0003-Fix-an-error-in-previous-commit.patch +26 -0
  31. data/ports/patches/libxml2/0004-Fix-potential-out-of-bound-access.patch +26 -0
  32. data/ports/patches/libxml2/0005-Detect-excessive-entities-expansion-upon-replacement.patch +158 -0
  33. data/ports/patches/libxml2/0006-Do-not-fetch-external-parsed-entities.patch +78 -0
  34. data/ports/patches/libxml2/0007-Enforce-XML_PARSER_EOF-state-handling-through-the-pa.patch +480 -0
  35. data/ports/patches/libxml2/0008-Improve-handling-of-xmlStopParser.patch +315 -0
  36. data/ports/patches/libxml2/0009-Fix-a-couple-of-return-without-value.patch +37 -0
  37. data/ports/patches/libxml2/0010-Keep-non-significant-blanks-node-in-HTML-parser.patch +2006 -0
  38. data/ports/patches/libxml2/0011-Do-not-fetch-external-parameter-entities.patch +39 -0
  39. data/ports/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch +222 -0
  40. data/ports/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch +53 -0
  41. data/ports/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch +60 -0
  42. data/ports/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch +42 -0
  43. data/ports/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch +164 -0
  44. data/ports/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch +587 -0
  45. data/ports/patches/libxslt/0008-Fix-direct-pattern-matching.patch +80 -0
  46. data/ports/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch +185 -0
  47. data/ports/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch +126 -0
  48. data/ports/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch +25 -0
  49. data/ports/patches/libxslt/0014-Fix-for-bug-436589.patch +43 -0
  50. data/ports/patches/libxslt/0015-Fix-mkdir-for-mingw.patch +41 -0
  51. data/ports/patches/xmlsec1/.keep +0 -0
  52. data/spec/fixtures/cert/server.crt +14 -0
  53. data/spec/fixtures/cert/server.csr +11 -0
  54. data/spec/fixtures/cert/server.key.decrypted +15 -0
  55. data/spec/fixtures/cert/server.key.encrypted +18 -0
  56. data/spec/fixtures/rsa.pem +15 -0
  57. data/spec/fixtures/rsa.pub +6 -0
  58. data/spec/fixtures/sign2-doc.xml +6 -0
  59. data/spec/fixtures/sign2-result.xml +24 -0
  60. data/spec/fixtures/sign3-result.xml +37 -0
  61. data/spec/lib/nokogiri/xml/document/encryption_and_decryption_spec.rb +22 -0
  62. data/spec/lib/nokogiri/xml/document/signing_and_verifying_spec.rb +77 -0
  63. data/spec/spec_helper.rb +10 -0
  64. metadata +251 -0
@@ -0,0 +1,95 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ // TODO the signature context probably should be a ruby instance variable
4
+ // and separate object, instead of being allocated/freed in each method.
5
+
6
+ VALUE sign_with_key(VALUE self, VALUE rb_key_name, VALUE rb_rsa_key) {
7
+ xmlDocPtr doc;
8
+ xmlNodePtr signNode = NULL;
9
+ xmlNodePtr refNode = NULL;
10
+ xmlNodePtr keyInfoNode = NULL;
11
+ xmlSecDSigCtxPtr dsigCtx = NULL;
12
+ char *keyName;
13
+ char *rsaKey;
14
+ unsigned int rsaKeyLength;
15
+
16
+ Data_Get_Struct(self, xmlDoc, doc);
17
+ rsaKey = RSTRING_PTR(rb_rsa_key);
18
+ rsaKeyLength = RSTRING_LEN(rb_rsa_key);
19
+ keyName = RSTRING_PTR(rb_key_name);
20
+
21
+ // create signature template for RSA-SHA1 enveloped signature
22
+ signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
23
+ xmlSecTransformRsaSha1Id, NULL);
24
+ if (signNode == NULL) {
25
+ rb_raise(rb_eSigningError, "failed to create signature template");
26
+ goto done;
27
+ }
28
+
29
+ // add <dsig:Signature/> node to the doc
30
+ xmlAddChild(xmlDocGetRootElement(doc), signNode);
31
+
32
+ // add reference
33
+ refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id,
34
+ NULL, NULL, NULL);
35
+ if(refNode == NULL) {
36
+ rb_raise(rb_eSigningError, "failed to add reference to signature template");
37
+ goto done;
38
+ }
39
+
40
+ // add enveloped transform
41
+ if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) {
42
+ rb_raise(rb_eSigningError, "failed to add enveloped transform to reference");
43
+ goto done;
44
+ }
45
+
46
+ // add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name in the signed
47
+ // document
48
+ keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL);
49
+ if(keyInfoNode == NULL) {
50
+ rb_raise(rb_eSigningError, "failed to add key info");
51
+ goto done;
52
+ }
53
+ if(xmlSecTmplKeyInfoAddKeyName(keyInfoNode, NULL) == NULL) {
54
+ rb_raise(rb_eSigningError, "failed to add key name");
55
+ goto done;
56
+ }
57
+
58
+ // create signature context, we don't need keys manager in this example
59
+ dsigCtx = xmlSecDSigCtxCreate(NULL);
60
+ if(dsigCtx == NULL) {
61
+ rb_raise(rb_eSigningError, "failed to create signature context");
62
+ goto done;
63
+ }
64
+
65
+ // load private key, assuming that there is no password
66
+ dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)rsaKey,
67
+ rsaKeyLength,
68
+ xmlSecKeyDataFormatPem,
69
+ NULL, // password
70
+ NULL,
71
+ NULL);
72
+ if(dsigCtx->signKey == NULL) {
73
+ rb_raise(rb_eSigningError, "failed to load private pem key");
74
+ goto done;
75
+ }
76
+
77
+ // set key name
78
+ if(xmlSecKeySetName(dsigCtx->signKey, (xmlSecByte *)keyName) < 0) {
79
+ rb_raise(rb_eSigningError, "failed to set key name");
80
+ goto done;
81
+ }
82
+
83
+ // sign the template
84
+ if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) {
85
+ rb_raise(rb_eSigningError, "signature failed");
86
+ goto done;
87
+ }
88
+
89
+ done:
90
+ if(dsigCtx != NULL) {
91
+ xmlSecDSigCtxDestroy(dsigCtx);
92
+ }
93
+
94
+ return T_NIL;
95
+ }
@@ -0,0 +1,96 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ static xmlSecKeysMngrPtr getKeyManager(VALUE rb_certs) {
4
+ int i, numCerts = RARRAY_LEN(rb_certs);
5
+ xmlSecKeysMngrPtr keyManager = xmlSecKeysMngrCreate();
6
+ VALUE rb_cert;
7
+ char *cert;
8
+ unsigned int certLength;
9
+ int numSuccessful = 0;
10
+
11
+ if (keyManager == NULL) return NULL;
12
+
13
+ if (xmlSecCryptoAppDefaultKeysMngrInit(keyManager) < 0) {
14
+ rb_raise(rb_eKeystoreError, "could not initialize key manager");
15
+ xmlSecKeysMngrDestroy(keyManager);
16
+ return NULL;
17
+ }
18
+
19
+ for (i = 0; i < numCerts; i++) {
20
+ rb_cert = RARRAY_PTR(rb_certs)[i];
21
+ Check_Type(rb_cert, T_STRING);
22
+ cert = RSTRING_PTR(rb_cert);
23
+ certLength = RSTRING_LEN(rb_cert);
24
+
25
+ if(xmlSecCryptoAppKeysMngrCertLoadMemory(keyManager,
26
+ (xmlSecByte *)cert,
27
+ certLength,
28
+ xmlSecKeyDataFormatPem,
29
+ xmlSecKeyDataTypeTrusted) < 0) {
30
+ rb_warn("failed to load certificate at index %d", i);
31
+ } else {
32
+ numSuccessful++;
33
+ }
34
+ }
35
+
36
+ // note, numCerts could be zero, meaning that we should use system SSL certs
37
+ if (numSuccessful == 0 && numCerts != 0) {
38
+ rb_raise(rb_eKeystoreError, "Could not load any of the specified certificates for signature verification");
39
+ xmlSecKeysMngrDestroy(keyManager);
40
+ return NULL;
41
+ }
42
+
43
+ return keyManager;
44
+ }
45
+
46
+ VALUE verify_signature_with_certificates(VALUE self, VALUE rb_certs) {
47
+ xmlDocPtr doc;
48
+ xmlNodePtr node = NULL;
49
+ xmlSecDSigCtxPtr dsigCtx = NULL;
50
+ xmlSecKeysMngrPtr keyManager = NULL;
51
+ VALUE result = Qfalse;
52
+
53
+ Check_Type(rb_certs, T_ARRAY);
54
+ Data_Get_Struct(self, xmlDoc, doc);
55
+
56
+ // find start node
57
+ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
58
+ if(node == NULL) {
59
+ rb_raise(rb_eVerificationError, "start node not found");
60
+ goto done;
61
+ }
62
+
63
+ keyManager = getKeyManager(rb_certs);
64
+ if (keyManager == NULL) {
65
+ rb_raise(rb_eKeystoreError, "failed to create key manager");
66
+ goto done;
67
+ }
68
+
69
+ // create signature context, we don't need keys manager in this example
70
+ dsigCtx = xmlSecDSigCtxCreate(keyManager);
71
+ if(dsigCtx == NULL) {
72
+ rb_raise(rb_eVerificationError, "failed to create signature context");
73
+ goto done;
74
+ }
75
+
76
+ // verify signature
77
+ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
78
+ rb_raise(rb_eVerificationError, "error occurred during signature verification");
79
+ goto done;
80
+ }
81
+
82
+ if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
83
+ result = Qtrue;
84
+ }
85
+
86
+ done:
87
+ if(dsigCtx != NULL) {
88
+ xmlSecDSigCtxDestroy(dsigCtx);
89
+ }
90
+
91
+ if (keyManager != NULL) {
92
+ xmlSecKeysMngrDestroy(keyManager);
93
+ }
94
+
95
+ return result;
96
+ }
@@ -0,0 +1,106 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ static int addRubyKeyToManager(VALUE rb_key, VALUE rb_value, VALUE rb_manager) {
4
+ xmlSecKeysMngrPtr keyManager = (xmlSecKeysMngrPtr)rb_manager;
5
+ char *keyName, *keyData;
6
+ unsigned int keyDataLength;
7
+ xmlSecKeyPtr key;
8
+
9
+ Check_Type(rb_key, T_STRING);
10
+ Check_Type(rb_value, T_STRING);
11
+ keyName = RSTRING_PTR(rb_key);
12
+ keyData = RSTRING_PTR(rb_value);
13
+ keyDataLength = RSTRING_LEN(rb_value);
14
+
15
+ // load key
16
+ key = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)keyData,
17
+ keyDataLength,
18
+ xmlSecKeyDataFormatPem,
19
+ NULL, // password
20
+ NULL, NULL);
21
+ if (key == NULL) {
22
+ rb_warn("failed to load '%s' public or private pem key", keyName);
23
+ return ST_CONTINUE;
24
+ }
25
+
26
+ // set key name
27
+ if (xmlSecKeySetName(key, BAD_CAST keyName) < 0) {
28
+ rb_warn("failed to set key name for key '%s'", keyName);
29
+ return ST_CONTINUE;
30
+ }
31
+
32
+ // add key to key manager; from now on the manager is responsible for
33
+ // destroying the key
34
+ if (xmlSecCryptoAppDefaultKeysMngrAdoptKey(keyManager, key) < 0) {
35
+ rb_warn("failed to add key '%s' to key manager", keyName);
36
+ return ST_CONTINUE;
37
+ }
38
+
39
+ return ST_CONTINUE;
40
+ }
41
+
42
+ static xmlSecKeysMngrPtr getKeyManager(VALUE rb_hash) {
43
+ xmlSecKeysMngrPtr keyManager = xmlSecKeysMngrCreate();
44
+ if (keyManager == NULL) return NULL;
45
+ if (xmlSecCryptoAppDefaultKeysMngrInit(keyManager) < 0) {
46
+ rb_raise(rb_eKeystoreError, "could not initialize key manager");
47
+ xmlSecKeysMngrDestroy(keyManager);
48
+ return NULL;
49
+ }
50
+
51
+ rb_hash_foreach(rb_hash, addRubyKeyToManager, (VALUE)keyManager);
52
+
53
+ return keyManager;
54
+ }
55
+
56
+ VALUE verify_signature_with_named_keys(VALUE self, VALUE rb_hash) {
57
+ xmlDocPtr doc;
58
+ xmlNodePtr node = NULL;
59
+ xmlSecDSigCtxPtr dsigCtx = NULL;
60
+ xmlSecKeysMngrPtr keyManager = NULL;
61
+ VALUE result = Qfalse;
62
+
63
+ Check_Type(rb_hash, T_HASH);
64
+ Data_Get_Struct(self, xmlDoc, doc);
65
+
66
+ // find start node
67
+ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
68
+ if(node == NULL) {
69
+ rb_raise(rb_eVerificationError, "start node not found");
70
+ goto done;
71
+ }
72
+
73
+ keyManager = getKeyManager(rb_hash);
74
+ if (keyManager == NULL) {
75
+ rb_raise(rb_eKeystoreError, "failed to create key manager");
76
+ goto done;
77
+ }
78
+
79
+ // create signature context, we don't need keys manager in this example
80
+ dsigCtx = xmlSecDSigCtxCreate(keyManager);
81
+ if(dsigCtx == NULL) {
82
+ rb_raise(rb_eVerificationError, "failed to create signature context");
83
+ goto done;
84
+ }
85
+
86
+ // verify signature
87
+ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
88
+ rb_raise(rb_eVerificationError, "signature could not be verified");
89
+ goto done;
90
+ }
91
+
92
+ if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
93
+ result = Qtrue;
94
+ }
95
+
96
+ done:
97
+ if(dsigCtx != NULL) {
98
+ xmlSecDSigCtxDestroy(dsigCtx);
99
+ }
100
+
101
+ if (keyManager != NULL) {
102
+ xmlSecKeysMngrDestroy(keyManager);
103
+ }
104
+
105
+ return result;
106
+ }
@@ -0,0 +1,56 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ VALUE verify_signature_with_rsa_key(VALUE self, VALUE rb_rsa_key) {
4
+ xmlDocPtr doc;
5
+ xmlNodePtr node = NULL;
6
+ xmlSecDSigCtxPtr dsigCtx = NULL;
7
+ char *rsaKey;
8
+ unsigned int rsaKeyLength;
9
+ VALUE result = Qfalse;
10
+
11
+ Data_Get_Struct(self, xmlDoc, doc);
12
+ rsaKey = RSTRING_PTR(rb_rsa_key);
13
+ rsaKeyLength = RSTRING_LEN(rb_rsa_key);
14
+
15
+ // find start node
16
+ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
17
+ if(node == NULL) {
18
+ rb_raise(rb_eVerificationError, "start node not found");
19
+ goto done;
20
+ }
21
+
22
+ // create signature context, we don't need keys manager in this example
23
+ dsigCtx = xmlSecDSigCtxCreate(NULL);
24
+ if(dsigCtx == NULL) {
25
+ rb_raise(rb_eVerificationError, "failed to create signature context");
26
+ goto done;
27
+ }
28
+
29
+ // load public key
30
+ dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)rsaKey,
31
+ rsaKeyLength,
32
+ xmlSecKeyDataFormatPem,
33
+ NULL, // password
34
+ NULL, NULL);
35
+ if(dsigCtx->signKey == NULL) {
36
+ rb_raise(rb_eVerificationError, "failed to load public pem key");
37
+ goto done;
38
+ }
39
+
40
+ // verify signature
41
+ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
42
+ rb_raise(rb_eVerificationError, "signature could not be verified");
43
+ goto done;
44
+ }
45
+
46
+ if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
47
+ result = Qtrue;
48
+ }
49
+
50
+ done:
51
+ if(dsigCtx != NULL) {
52
+ xmlSecDSigCtxDestroy(dsigCtx);
53
+ }
54
+
55
+ return result;
56
+ }
@@ -0,0 +1,12 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ /* not actually called anywhere right now, but here for posterity */
4
+ void Shutdown_xmlsecrb() {
5
+ xmlSecCryptoShutdown();
6
+ xmlSecCryptoAppShutdown();
7
+ xmlSecShutdown();
8
+ xsltCleanupGlobals();
9
+ #ifndef XMLSEC_NO_XSLT
10
+ xsltCleanupGlobals();
11
+ #endif /* XMLSEC_NO_XSLT */
12
+ }
@@ -0,0 +1,39 @@
1
+ #ifndef XMLSECRB_H
2
+ #define XMLSECRB_H
3
+
4
+ #include <ruby.h>
5
+
6
+ #include <libxml/tree.h>
7
+ #include <libxml/xmlmemory.h>
8
+ #include <libxml/parser.h>
9
+ #include <libxml/xmlstring.h>
10
+
11
+ #include <libxslt/xslt.h>
12
+
13
+ #include <xmlsec/xmlsec.h>
14
+ #include <xmlsec/xmltree.h>
15
+ #include <xmlsec/xmldsig.h>
16
+ #include <xmlsec/xmlenc.h>
17
+ #include <xmlsec/templates.h>
18
+ #include <xmlsec/crypto.h>
19
+ #include <xmlsec/dl.h>
20
+
21
+ VALUE sign_with_key(VALUE self, VALUE rb_key_name, VALUE rb_rsa_key);
22
+ VALUE sign_with_certificate(VALUE self, VALUE rb_key_name, VALUE rb_rsa_key, VALUE rb_cert);
23
+ VALUE verify_signature_with_rsa_key(VALUE self, VALUE rb_rsa_key);
24
+ VALUE verify_signature_with_named_keys(VALUE self, VALUE rb_keys);
25
+ VALUE verify_signature_with_certificates(VALUE self, VALUE rb_certs);
26
+ VALUE encrypt_with_key(VALUE self, VALUE rb_key_name, VALUE rb_key);
27
+ VALUE decrypt_with_key(VALUE self, VALUE rb_key_name, VALUE rb_key);
28
+ VALUE set_id_attribute(VALUE self, VALUE rb_attr_name);
29
+
30
+ void Init_Nokogiri_ext(void);
31
+
32
+ extern VALUE rb_cNokogiri_XML_Document;
33
+ extern VALUE rb_eSigningError;
34
+ extern VALUE rb_eVerificationError;
35
+ extern VALUE rb_eKeystoreError;
36
+ extern VALUE rb_eEncryptionError;
37
+ extern VALUE rb_eDecryptionError;
38
+
39
+ #endif // XMLSECRB_H
@@ -0,0 +1 @@
1
+ require 'xmlsec'
@@ -0,0 +1,110 @@
1
+ require "xmlsec/version"
2
+ require 'nokogiri'
3
+ require 'nokogiri_ext_xmlsec'
4
+
5
+ class Nokogiri::XML::Document
6
+ # Signs this document, and then returns it.
7
+ #
8
+ # Examples:
9
+ #
10
+ # doc.sign! key: 'rsa-private-key'
11
+ # doc.sign! key: 'rsa-private-key', name: 'key-name'
12
+ # doc.sign! x509: 'x509 certificate', key: 'cert private key'
13
+ # doc.sign! x509: 'x509 certificate', key: 'cert private key',
14
+ # name: 'key-name'
15
+ #
16
+ # You can also use `:cert` or `:certificate` as aliases for `:x509`.
17
+ #
18
+ def sign! opts
19
+ if (cert = opts[:x509]) || (cert = opts[:cert]) || (cert = opts[:certificate])
20
+ raise "need a private :key" unless opts[:key]
21
+ sign_with_certificate opts[:name].to_s, opts[:key], cert
22
+ elsif opts[:key]
23
+ sign_with_key opts[:name].to_s, opts[:key]
24
+ else
25
+ raise "No private :key was given"
26
+ end
27
+ self
28
+ end
29
+
30
+ # Verifies the signature on the current document.
31
+ #
32
+ # Returns `true` if the signature is valid, `false` otherwise.
33
+ #
34
+ # Examples:
35
+ #
36
+ # # Try to validate with the given public or private key
37
+ # doc.verify_with key: 'rsa-key'
38
+ #
39
+ # # Try to validate with a set of keys. It will try to match
40
+ # # based on the contents of the `KeyName` element.
41
+ # doc.verify_with({
42
+ # 'key-name' => 'x509 certificate',
43
+ # 'another-key-name' => 'rsa-public-key'
44
+ # })
45
+ #
46
+ # # Try to validate with a trusted certificate
47
+ # doc.verify_with(x509: 'certificate')
48
+ #
49
+ # # Try to validate with a set of certificates, any one of which
50
+ # # can match
51
+ # doc.verify_with(x509: ['cert1', 'cert2'])
52
+ #
53
+ # You can also use `:cert` or `:certificate` or `:certs` or
54
+ # `:certificates` as aliases for `:x509`.
55
+ #
56
+ def verify_with opts_or_keys
57
+ if (certs = opts_or_keys[:x509]) ||
58
+ (certs = opts_or_keys[:cert]) ||
59
+ (certs = opts_or_keys[:certs]) ||
60
+ (certs = opts_or_keys[:certificate]) ||
61
+ (certs = opts_or_keys[:certificates])
62
+ certs = [certs] unless certs.kind_of?(Array)
63
+ verify_with_certificates certs
64
+ elsif opts_or_keys[:key]
65
+ verify_with_rsa_key opts_or_keys[:key]
66
+ else
67
+ verify_with_named_keys opts_or_keys
68
+ end
69
+ end
70
+
71
+ # Attempts to verify the signature of this document using only certificates
72
+ # installed on the system. This is equivalent to calling
73
+ # `verify_with certificates: []` (that is, an empty array).
74
+ #
75
+ def verify_signature
76
+ verify_with_certificates []
77
+ end
78
+
79
+ # Encrypts the current document, then returns it.
80
+ #
81
+ # Examples:
82
+ #
83
+ # # encrypt with a public key and optional key name
84
+ # doc.encrypt! key: 'public-key', name: 'name'
85
+ #
86
+ def encrypt! opts
87
+ if opts[:key]
88
+ encrypt_with_key opts[:name].to_s, opts[:key]
89
+ else
90
+ raise "public :key is required for encryption"
91
+ end
92
+ self
93
+ end
94
+
95
+ # Decrypts the current document, then returns it.
96
+ #
97
+ # Examples:
98
+ #
99
+ # # decrypt with a specific private key
100
+ # doc.decrypt! key: 'private-key'
101
+ #
102
+ def decrypt! opts
103
+ if opts[:key]
104
+ decrypt_with_key opts[:name].to_s, opts[:key]
105
+ else
106
+ raise 'inadequate options specified for decryption'
107
+ end
108
+ self
109
+ end
110
+ end