Setup a basic project and program driver

This commit is contained in:
Nick Chambers 2025-03-14 12:53:20 -05:00
commit e5729ee0e6
7 changed files with 180 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/scratch/
/jasn1-*.gem
.DS_Store

7
LICENSE Normal file
View file

@ -0,0 +1,7 @@
Copyright (c) Nick Chambers <uplime@spookyinternet.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# Jasn1
Display an X.509 DER-encoded certificate as a JSON string.

18
bin/jasn1 Executable file
View file

@ -0,0 +1,18 @@
#!/usr/bin/env ruby
if $PROGRAM_NAME.start_with?("bin/")
$LOAD_PATH.unshift(File.expand_path("./lib", "."))
end
require "jasn1"
opts = Jasn1::Options::Options.new do |opt|
opt.arg(key: "format", values: ["openssl", "verbose", "basic"])
opt.arg(key: "critical", default: false)
end
opts.args.each do |filename|
contents = File.open(filename) do |file|
file.read
end
end

9
jasn1.gemspec Normal file
View file

@ -0,0 +1,9 @@
Gem::Specification.new do |spec|
spec.name = "jasn1"
spec.version = "0.0.1"
spec.summary = "Display an X.509 DER-encoded certificate as a JSON string."
spec.authors = ["uplime"]
spec.executables = ["jasn1"]
spec.files = ["lib/jasn1.rb"]
spec.license = "MIT"
end

2
lib/jasn1.rb Normal file
View file

@ -0,0 +1,2 @@
require "jasn1/asn1"
require "jasn1/options"

138
lib/jasn1/options.rb Normal file
View file

@ -0,0 +1,138 @@
module Jasn1
module Options
class NoKeyError < StandardError
end
class AmbiguousTypeError < StandardError
end
class TypeValueMismatchError < StandardError
end
class DefaultTypeMismatchError < StandardError
end
class UnrecognizedFlagError < StandardError
end
class NoValueError < StandardError
end
class UnsupportedValueError < StandardError
end
class Option
attr_reader :type, :values
attr_accessor :value
def initialize(type, values, default)
@type = type
@values = values
@value = default
end
end
class OptionsManager
attr_reader :opts
def initialize
@opts = { }
@strict = false
end
def arg(key: "", type: nil, values: [], default: nil)
if key.empty?
raise NoKeyError
end
if default.nil? and not values.empty?
default = values.first
end
if type.nil?
if not default.nil?
type = default.class
elsif not values.empty?
type = values.first.class
else
raise AmbiguousTypeError
end
else
bad_values = values.filter do |value|
not value.is_a?(type)
end
if not bad_values.empty?
raise TypeValueMismatchError
elsif not default.nil? and not default.is_a?(type)
raise DefaultTypeMismatchError
end
end
@opts[key] = Option.new(type, values, default)
end
def boolean?(key)
[TrueClass, FalseClass].include? @opts[key].type
end
end
class Options
attr_reader :args
def initialize(args=ARGV)
if not block_given?
return
end
scanning = true
@args = args.clone
@mgr = OptionsManager.new
yield @mgr
while not @args.empty? and scanning
if @args.first == "--"
@args.shift
scanning = false
elsif @args.first[0] != "-"
scanning = false
end
if scanning
opt = @args.shift[1..]
flip = false
if opt.start_with?("no-")
opt = opt[3..]
flip = true
end
key, val = opt.split("=", 2)
if not @mgr.opts.key? key
raise UnrecognizedFlagError
end
if @mgr.boolean? key
@mgr.opts[key].value = if val.nil?
!flip
else
somehow_convert_to_boolean val
end
elsif val.nil?
raise NoValueError
elsif not @mgr.opts[key].values.include? val
raise UnsupportedValueError
else
@mgr.opts[key].value = @mgr.opts[key].type.new(val)
end
end
end
end
def [](key)
@mgr.opts[idx].value
end
end
end
end