mirror of
				https://github.com/therootcompany/acme.js.git
				synced 2024-11-16 17:29:00 +00:00 
			
		
		
		
	closer to v1
This commit is contained in:
		
							parent
							
								
									b630c118cc
								
							
						
					
					
						commit
						263eed0475
					
				
							
								
								
									
										113
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								README.md
									
									
									
									
									
								
							| @ -1,41 +1,12 @@ | |||||||
| acme-v2.js | acme-v2.js (draft 11) | ||||||
| ========== | ========== | ||||||
| 
 | 
 | ||||||
| | Sponsored by [ppl](https://ppl.family) | | Sponsored by [ppl](https://ppl.family) | ||||||
| 
 | 
 | ||||||
| A framework for building letsencrypt clients (and other ACME v2 clients), forked from `le-acme-core.js`. | A framework for building letsencrypt v2 (IETF ACME draft 11), forked from `le-acme-core.js`. | ||||||
| 
 | 
 | ||||||
| Summary of spec that I'm working off of here: https://git.coolaj86.com/coolaj86/greenlock.js/issues/5#issuecomment-8 | Summary of spec that I'm working off of here: https://git.coolaj86.com/coolaj86/greenlock.js/issues/5#issuecomment-8 | ||||||
| 
 | 
 | ||||||
| In progress |  | ||||||
| 
 |  | ||||||
| * Mar 15, 2018 - get directory |  | ||||||
| * Mar 15, 2018 - get nonce |  | ||||||
| * Mar 15, 2018 - generate account keypair |  | ||||||
| * Mar 15, 2018 - create account |  | ||||||
| * Mar 16, 2018 - new order |  | ||||||
| * Mar 16, 2018 - get challenges |  | ||||||
| * Mar 20, 2018 - respond to challenges |  | ||||||
| * Mar 20, 2018 - generate domain keypair |  | ||||||
| * Mar 20, 2018 - finalize order (submit csr) |  | ||||||
| * Mar 20, 2018 - poll for status |  | ||||||
| * Mar 20, 2018 - download certificate |  | ||||||
| * Mar 20, 2018 - SUCCESS - got a test certificate (hard-coded) |  | ||||||
| * Mar 21, 2018 - can now accept values (not hard coded) |  | ||||||
| * Mar 21, 2018 - *mostly* matches le-acme-core.js API |  | ||||||
| * Apr  5, 2018 - completely match api for acme v1 (le-acme-core.js) |  | ||||||
| * Apr  5, 2018 - test wildcard |  | ||||||
| * Apr  5, 2018 - test two subdomains |  | ||||||
| * Apr  5, 2018 - test subdomains and its wildcard |  | ||||||
| * Apr  5, 2018 - test http and dns challenges (success and failure) |  | ||||||
| * Apr  5, 2018 - export http and dns challenge tests |  | ||||||
| * Apr 10, 2018 - tested backwards-compatibility using greenlock.js |  | ||||||
| 
 |  | ||||||
| Todo |  | ||||||
| 
 |  | ||||||
| * support ECDSA keys |  | ||||||
| * Apr  5, 2018 - appears that sometimes 'pending' status cannot be progressed to 'processing' nor 'deactivated' |  | ||||||
| 
 |  | ||||||
| ## Let's Encrypt Directory URLs | ## Let's Encrypt Directory URLs | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| @ -48,7 +19,48 @@ https://acme-v02.api.letsencrypt.org/directory | |||||||
| https://acme-staging-v02.api.letsencrypt.org/directory | https://acme-staging-v02.api.letsencrypt.org/directory | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## API | ## Two API versions, Two Implementations | ||||||
|  | 
 | ||||||
|  | This library (acme-v2.js) supports ACME [*draft 11*](https://tools.ietf.org/html/draft-ietf-acme-acme-11), | ||||||
|  | otherwise known as Let's Encrypt v2 (or v02). | ||||||
|  | 
 | ||||||
|  |   * ACME draft 11 | ||||||
|  |   * Let's Encrypt v2 | ||||||
|  |   * Let's Encrypt v02 | ||||||
|  | 
 | ||||||
|  | The predecessor (le-acme-core) supports Let's Encrypt v1 (or v01), which was a | ||||||
|  | [hodge-podge of various drafts](https://github.com/letsencrypt/boulder/blob/master/docs/acme-divergences.md) | ||||||
|  | of the ACME spec early on. | ||||||
|  | 
 | ||||||
|  |   * ACME early draft | ||||||
|  |   * Let's Encrypt v1 | ||||||
|  |   * Let's Encrypt v01 | ||||||
|  | 
 | ||||||
|  | This library maintains compatibility with le-acme-core so that it can be used as a **drop-in replacement** | ||||||
|  | and requires **no changes to existing code**, | ||||||
|  | but also provides an updated API more congruent with draft 11. | ||||||
|  | 
 | ||||||
|  | ## le-acme-core-compatible API (recommended) | ||||||
|  | 
 | ||||||
|  | Status: Stable, Locked, Bugfix-only | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | var RSA = require('rsa-compat').RSA; | ||||||
|  | var acme = require('acme-v2/compat.js').ACME.create({ RSA: RSA }); | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // Use exactly the same as le-acme-core | ||||||
|  | // | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | See documentation at <https://git.coolaj86.com/coolaj86/le-acme-core.js> | ||||||
|  | 
 | ||||||
|  | ## draft API (dev) | ||||||
|  | 
 | ||||||
|  | Status: Almost stable, not locked | ||||||
|  | 
 | ||||||
|  | This API is a simple evolution of le-acme-core, | ||||||
|  | but tries to provide a better mapping to the new draft 11 APIs. | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| var ACME = require('acme-v2').ACME.create({ | var ACME = require('acme-v2').ACME.create({ | ||||||
| @ -110,6 +122,41 @@ Helpers & Stuff | |||||||
| 
 | 
 | ||||||
| ```javascript | ```javascript | ||||||
| // Constants | // Constants | ||||||
| ACME.acmeChallengePrefix                // /.well-known/acme-challenge/ | ACME.challengePrefixes['http-01']             // '/.well-known/acme-challenge' | ||||||
|  | ACME.challengePrefixes['dns-01']              // '_acme-challenge' | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | Todo | ||||||
|  | ---- | ||||||
|  | 
 | ||||||
|  | * support ECDSA keys | ||||||
|  | * Apr  5, 2018 - appears that sometimes 'pending' status cannot be progressed to 'processing' nor 'deactivated' | ||||||
|  |   * this may be a bug in the staging API as it appears it cannot be cancelled either, but returns success status code | ||||||
|  | 
 | ||||||
|  | Changelog | ||||||
|  | --------- | ||||||
|  | 
 | ||||||
|  | * v1.0.0 | ||||||
|  |   * Compat API is ready for use | ||||||
|  |   * Eliminate debug logging | ||||||
|  | * Apr 10, 2018 - tested backwards-compatibility using greenlock.js | ||||||
|  | * Apr  5, 2018 - export http and dns challenge tests | ||||||
|  | * Apr  5, 2018 - test http and dns challenges (success and failure) | ||||||
|  | * Apr  5, 2018 - test subdomains and its wildcard | ||||||
|  | * Apr  5, 2018 - test two subdomains | ||||||
|  | * Apr  5, 2018 - test wildcard | ||||||
|  | * Apr  5, 2018 - completely match api for acme v1 (le-acme-core.js) | ||||||
|  | * Mar 21, 2018 - *mostly* matches le-acme-core.js API | ||||||
|  | * Mar 21, 2018 - can now accept values (not hard coded) | ||||||
|  | * Mar 20, 2018 - SUCCESS - got a test certificate (hard-coded) | ||||||
|  | * Mar 20, 2018 - download certificate | ||||||
|  | * Mar 20, 2018 - poll for status | ||||||
|  | * Mar 20, 2018 - finalize order (submit csr) | ||||||
|  | * Mar 20, 2018 - generate domain keypair | ||||||
|  | * Mar 20, 2018 - respond to challenges | ||||||
|  | * Mar 16, 2018 - get challenges | ||||||
|  | * Mar 16, 2018 - new order | ||||||
|  | * Mar 15, 2018 - create account | ||||||
|  | * Mar 15, 2018 - generate account keypair | ||||||
|  | * Mar 15, 2018 - get nonce | ||||||
|  | * Mar 15, 2018 - get directory | ||||||
|  | |||||||
| @ -50,6 +50,7 @@ function create(deps) { | |||||||
|   }; |   }; | ||||||
|   acme2.stagingServerUrl = module.exports.defaults.stagingServerUrl; |   acme2.stagingServerUrl = module.exports.defaults.stagingServerUrl; | ||||||
|   acme2.productionServerUrl = module.exports.defaults.productionServerUrl; |   acme2.productionServerUrl = module.exports.defaults.productionServerUrl; | ||||||
|  |   acme2.acmeChallengePrefix = module.exports.defaults.acmeChallengePrefix; | ||||||
|   return acme2; |   return acme2; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -63,11 +64,12 @@ module.exports.defaults = { | |||||||
| //, keyType:                'rsa' // ecdsa
 | //, keyType:                'rsa' // ecdsa
 | ||||||
| //, keySize:                2048 // 256
 | //, keySize:                2048 // 256
 | ||||||
| , rsaKeySize:             2048 // 256
 | , rsaKeySize:             2048 // 256
 | ||||||
|  | , acmeChallengePrefix:    '/.well-known/acme-challenge/'; | ||||||
| }; | }; | ||||||
| Object.keys(module.exports.defaults).forEach(function (key) { | Object.keys(module.exports.defaults).forEach(function (key) { | ||||||
|   module.exports.ACME[key] = module.exports.defaults[key]; |   module.exports.ACME[key] = module.exports.defaults[key]; | ||||||
| }); | }); | ||||||
| Object.keys(ACME2).forEach(function (key) { | Object.keys(ACME2).forEach(function (key) { | ||||||
|   module.exports.ACME[key] = ACME2[key]; |   module.exports.ACME[key] = ACME2[key]; | ||||||
|   module.exports.ACME.create = create; |  | ||||||
| }); | }); | ||||||
|  | module.exports.ACME.create = create; | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								node.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								node.js
									
									
									
									
									
								
							| @ -8,15 +8,13 @@ | |||||||
| 
 | 
 | ||||||
| var ACME = module.exports.ACME = {}; | var ACME = module.exports.ACME = {}; | ||||||
| 
 | 
 | ||||||
| ACME.acmeChallengePrefix = '/.well-known/acme-challenge/'; | ACME.challengePrefixes = { | ||||||
| ACME.acmeChallengeDnsPrefix = '_acme-challenge'; |  | ||||||
| ACME.acmeChallengePrefixes = { |  | ||||||
|   'http-01': '/.well-known/acme-challenge' |   'http-01': '/.well-known/acme-challenge' | ||||||
| , 'dns-01': '_acme-challenge' | , 'dns-01': '_acme-challenge' | ||||||
| }; | }; | ||||||
| ACME.challengeTests = { | ACME.challengeTests = { | ||||||
|   'http-01': function (me, auth) { |   'http-01': function (me, auth) { | ||||||
|     var url = 'http://' + auth.hostname + ACME.acmeChallengePrefixes['http-01'] + '/' + auth.token; |     var url = 'http://' + auth.hostname + ACME.challengePrefixes['http-01'] + '/' + auth.token; | ||||||
|     return me._request({ url: url }).then(function (resp) { |     return me._request({ url: url }).then(function (resp) { | ||||||
|       var err; |       var err; | ||||||
| 
 | 
 | ||||||
| @ -32,7 +30,7 @@ ACME.challengeTests = { | |||||||
| , 'dns-01': function (me, auth) { | , 'dns-01': function (me, auth) { | ||||||
|     return me._dig({ |     return me._dig({ | ||||||
|       type: 'TXT' |       type: 'TXT' | ||||||
|     , name: ACME.acmeChallengePrefixes['dns-01'] + '.' + auth.hostname |     , name: ACME.challengePrefixes['dns-01'] + '.' + auth.hostname | ||||||
|     }).then(function (ans) { |     }).then(function (ans) { | ||||||
|       var err; |       var err; | ||||||
| 
 | 
 | ||||||
| @ -562,9 +560,7 @@ ACME.create = function create(me) { | |||||||
|   if (!me) { me = {}; } |   if (!me) { me = {}; } | ||||||
|   //
 |   //
 | ||||||
|   me.debug = true; |   me.debug = true; | ||||||
|   me.acmeChallengePrefix = ACME.acmeChallengePrefix; |   me.challengePrefixes = ACME.challengePrefixes; | ||||||
|   me.acmeChallengeDnsPrefix = ACME.acmeChallengeDnsPrefix; |  | ||||||
|   me.acmeChallengePrefixes = ACME.acmeChallengePrefixes; |  | ||||||
|   me.RSA = me.RSA || require('rsa-compat').RSA; |   me.RSA = me.RSA || require('rsa-compat').RSA; | ||||||
|   me.request = me.request || require('request'); |   me.request = me.request || require('request'); | ||||||
|   me._dig = function (query) { |   me._dig = function (query) { | ||||||
|  | |||||||
| @ -31,11 +31,11 @@ module.exports.run = function run(web, chType, email, accountKeypair, domainKeyp | |||||||
|         console.log(""); |         console.log(""); | ||||||
| 
 | 
 | ||||||
|         if ('http-01' === opts.type) { |         if ('http-01' === opts.type) { | ||||||
|           pathname = opts.hostname + acme2.acmeChallengePrefixes['http-01'] + "/" + opts.token; |           pathname = opts.hostname + acme2.challengePrefixes['http-01'] + "/" + opts.token; | ||||||
|           console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + pathname + "'"); |           console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + pathname + "'"); | ||||||
|           console.log("echo '" + opts.keyAuthorization + "' > '" + pathname + "'"); |           console.log("echo '" + opts.keyAuthorization + "' > '" + pathname + "'"); | ||||||
|         } else if ('dns-01' === opts.type) { |         } else if ('dns-01' === opts.type) { | ||||||
|           pathname = acme2.acmeChallengeDnsPrefix + "." + opts.hostname.replace(/^\*\./, ''); |           pathname = acme2.challengePrefixes['dns-01'] + "." + opts.hostname.replace(/^\*\./, ''); | ||||||
|           console.log("Put the string '" + opts.dnsAuthorization + "' into the TXT record '" + pathname + "'"); |           console.log("Put the string '" + opts.dnsAuthorization + "' into the TXT record '" + pathname + "'"); | ||||||
|           console.log("ddig TXT " + pathname + " '" + opts.dnsAuthorization + "'"); |           console.log("ddig TXT " + pathname + " '" + opts.dnsAuthorization + "'"); | ||||||
|         } else { |         } else { | ||||||
|  | |||||||
| @ -33,11 +33,11 @@ module.exports.run = function run(web, chType, email, accountKeypair, domainKeyp | |||||||
|           console.log(""); |           console.log(""); | ||||||
| 
 | 
 | ||||||
|           if ('http-01' === opts.type) { |           if ('http-01' === opts.type) { | ||||||
|             pathname = opts.hostname + acme2.acmeChallengePrefixes['http-01'] + "/" + opts.token; |             pathname = opts.hostname + acme2.challengePrefixes['http-01'] + "/" + opts.token; | ||||||
|             console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + pathname + "'"); |             console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + pathname + "'"); | ||||||
|             console.log("echo '" + opts.keyAuthorization + "' > '" + pathname + "'"); |             console.log("echo '" + opts.keyAuthorization + "' > '" + pathname + "'"); | ||||||
|           } else if ('dns-01' === opts.type) { |           } else if ('dns-01' === opts.type) { | ||||||
|             pathname = acme2.acmeChallengeDnsPrefix + "." + opts.hostname.replace(/^\*\./, '');; |             pathname = acme2.challengePrefixes['dns-01'] + "." + opts.hostname.replace(/^\*\./, '');; | ||||||
|             console.log("Put the string '" + opts.dnsAuthorization + "' into the TXT record '" + pathname + "'"); |             console.log("Put the string '" + opts.dnsAuthorization + "' into the TXT record '" + pathname + "'"); | ||||||
|             console.log("ddig TXT " + pathname + " '" + opts.dnsAuthorization + "'"); |             console.log("ddig TXT " + pathname + " '" + opts.dnsAuthorization + "'"); | ||||||
|           } else { |           } else { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user