Class: ManifestV3
- Inherits:
-
Object
- Object
- ManifestV3
- Defined in:
- lib/ec2/amitools/manifestv3.rb
Overview
Manifest Version 3. Not backwards compatible
Defined Under Namespace
Classes: PartInformation
Constant Summary collapse
- VERSION_STRING =
'3'
- VERSION =
VERSION_STRING.to_i
Class Method Summary collapse
Instance Method Summary collapse
-
#ami_part_info_list ⇒ Object
Retrieve a list of AMI bundle parts info.
-
#authenticate(cert) ⇒ Object
Verify the signature.
-
#bundled_size ⇒ Object
Return the bundled size of the AMI.
-
#bundler_name ⇒ Object
Return the bundler name.
-
#bundler_release ⇒ Object
Return the bundler release.
-
#bundler_version ⇒ Object
Return the bundler version.
-
#cipher_algorithm ⇒ Object
Get cipher algorithm used.
-
#digest ⇒ Object
Return the AMI’s digest hex encoded.
-
#digest_algorithm ⇒ Object
Get digest algorithm used.
-
#doc ⇒ Object
for debugging only.
-
#ec2_encrypted_iv ⇒ Object
The ec2 encrypted initialization vector hex encoded.
-
#ec2_encrypted_key ⇒ Object
The ec2 encrypted key hex encoded.
-
#init(name, user, parts, size, bundled_size, user_encrypted_key, ec2_encrypted_key, cipher_algorithm, user_encrypted_iv, ec2_encrypted_iv, digest, digest_algorithm, privkey_filename, bundler_name = nil, bundler_version = nil, bundler_release = nil) ⇒ Object
Initialize the manifest with AMI information.
-
#initialize(xml = nil) ⇒ ManifestV3
constructor
A new instance of ManifestV3.
- #name ⇒ Object
-
#parts ⇒ Object
A list of PartInformation instances representing the AMI parts.
-
#sign(privkey_filename) ⇒ Object
Sign the manifest.
-
#signature ⇒ Object
Return the signature.
-
#size ⇒ Object
Return the size of the AMI.
-
#to_s ⇒ Object
Return the manifest as an XML string.
- #user ⇒ Object
-
#user_encrypted_iv ⇒ Object
The user encrypted initialization vector hex encoded.
-
#user_encrypted_key ⇒ Object
The user encrypted key hex encoded.
- #version ⇒ Object
Constructor Details
#initialize(xml = nil) ⇒ ManifestV3
Returns a new instance of ManifestV3.
34 35 36 37 38 39 40 41 42 |
# File 'lib/ec2/amitools/manifestv3.rb', line 34 def initialize( xml = nil ) if xml == nil @doc = REXML::Document.new else # Convert to string if necessary. xml = ( xml.kind_of?( IO ) ? xml.read : xml ) @doc = REXML::Document.new( xml ) end end |
Class Method Details
.version3?(xml) ⇒ Boolean
178 179 180 181 182 |
# File 'lib/ec2/amitools/manifestv3.rb', line 178 def ManifestV3::version3?( xml ) doc = REXML::Document.new( xml ) version = REXML::XPath.first( doc.root, 'version' ) return (version and version.text and version.text.to_i == VERSION) end |
Instance Method Details
#ami_part_info_list ⇒ Object
Retrieve a list of AMI bundle parts info. Each element is a hash with the following elements:
-
‘digest’
-
‘filename’
-
‘index’
228 229 230 231 232 233 234 235 236 237 |
# File 'lib/ec2/amitools/manifestv3.rb', line 228 def ami_part_info_list parts = Array.new REXML::XPath.each( @doc.root,'image/parts/part' ) do |part| index = part.attribute( 'index' ).to_s.to_i filename = REXML::XPath.first( part, 'filename' ).text digest = REXML::XPath.first( part, 'digest' ).text parts << { 'digest'=>digest, 'filename'=>filename, 'index'=>index } end return parts end |
#authenticate(cert) ⇒ Object
Verify the signature
300 301 302 303 304 |
# File 'lib/ec2/amitools/manifestv3.rb', line 300 def authenticate(cert) image_xml = XMLUtil.get_xml( @doc.to_s, 'image' ) pubkey = Crypto::cert2pubkey(cert) Crypto::authenticate(image_xml, Format::hex2bin(signature), pubkey) end |
#bundled_size ⇒ Object
Return the bundled size of the AMI.
257 258 259 |
# File 'lib/ec2/amitools/manifestv3.rb', line 257 def bundled_size() return get_element_text( 'image/bundled_size' ).to_i end |
#bundler_name ⇒ Object
Return the bundler name.
262 263 264 |
# File 'lib/ec2/amitools/manifestv3.rb', line 262 def bundler_name() return get_element_text('bundler/name') end |
#bundler_release ⇒ Object
Return the bundler release.
272 273 274 |
# File 'lib/ec2/amitools/manifestv3.rb', line 272 def bundler_release() return get_element_text('bundler/release') end |
#bundler_version ⇒ Object
Return the bundler version.
267 268 269 |
# File 'lib/ec2/amitools/manifestv3.rb', line 267 def bundler_version() return get_element_text('bundler/version') end |
#cipher_algorithm ⇒ Object
Get cipher algorithm used.
219 220 221 |
# File 'lib/ec2/amitools/manifestv3.rb', line 219 def cipher_algorithm() return REXML::XPath.first(@doc.root, 'image/ec2_encrypted_key/@algorithm').to_s end |
#digest ⇒ Object
Return the AMI’s digest hex encoded.
185 186 187 |
# File 'lib/ec2/amitools/manifestv3.rb', line 185 def digest() return get_element_text( 'image/digest' ) end |
#digest_algorithm ⇒ Object
Get digest algorithm used.
214 215 216 |
# File 'lib/ec2/amitools/manifestv3.rb', line 214 def digest_algorithm() return REXML::XPath.first(@doc.root, 'image/digest/@algorithm').to_s end |
#doc ⇒ Object
for debugging only
45 46 47 |
# File 'lib/ec2/amitools/manifestv3.rb', line 45 def doc @doc end |
#ec2_encrypted_iv ⇒ Object
The ec2 encrypted initialization vector hex encoded.
204 205 206 |
# File 'lib/ec2/amitools/manifestv3.rb', line 204 def ec2_encrypted_iv() return get_element_text( 'image/ec2_encrypted_iv' ) end |
#ec2_encrypted_key ⇒ Object
The ec2 encrypted key hex encoded.
194 195 196 |
# File 'lib/ec2/amitools/manifestv3.rb', line 194 def ec2_encrypted_key() return get_element_text('image/ec2_encrypted_key' ) end |
#init(name, user, parts, size, bundled_size, user_encrypted_key, ec2_encrypted_key, cipher_algorithm, user_encrypted_iv, ec2_encrypted_iv, digest, digest_algorithm, privkey_filename, bundler_name = nil, bundler_version = nil, bundler_release = nil) ⇒ Object
Initialize the manifest with AMI information. Return true
if the initialization was succesful. Raise an exception on error.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/ec2/amitools/manifestv3.rb', line 52 def init( name, user, # The user's account number. parts, # A list of parts filenames and digest pairs. size, # The size of the AMI in bytes. bundled_size, # The size of the bunled AMI in bytes. user_encrypted_key, # Hex encoded. ec2_encrypted_key, # Hex encoded. cipher_algorithm, # The cipher algorithm used to encrypted the AMI. user_encrypted_iv, # Hex encoded. ec2_encrypted_iv, # Hex encoded. digest, # Hex encoded. digest_algorithm, # The digest algorithm. privkey_filename, # The user's private key filename. bundler_name = nil, bundler_version = nil, bundler_release = nil ) # Check non-String parameter types. raise ArgumentError.new( "parts parameter type invalid" ) unless parts.is_a? Array # XML document. @doc = REXML::Document.new @doc << REXML::XMLDecl.new # manifest - the root element. manifest = REXML::Element.new( 'manifest' ) @doc.add_element( manifest ) # version - indicate the manifest version. version = REXML::Element.new( 'version' ) version.text = VERSION_STRING manifest.add_element( version ) # bundler information if bundler_name or bundler_version or bundler_release bundler_element = REXML::Element.new( 'bundler' ) manifest.add_element( bundler_element ) [['name', bundler_name ], ['version', bundler_version ], ['release', bundler_release ]].each do |element_name, text| if element_name element = REXML::Element.new( element_name ) element.text = text bundler_element.add_element( element ) end end end # image - the image element. image = REXML::Element.new( 'image' ) name_element = REXML::Element.new( 'name' ) name_element.text = name image.add_element( name_element ) manifest.add_element( image ) # user - the user's AWS access key ID. user_element = REXML::Element.new( 'user' ) user_element.text = user image.add_element( user_element ) # digest - the digest of the AMI. digest_element = REXML::Element.new( 'digest' ) digest_element.add_attribute( 'algorithm', digest_algorithm ) digest_element.add_text( digest ) image.add_element( digest_element ) # size - the size of the uncompressed AMI. size_element = REXML::Element.new( 'size' ) size_element.text = size.to_s image.add_element( size_element ) # size - the size of the uncompressed AMI. bundled_size_element = REXML::Element.new( 'bundled_size' ) bundled_size_element.text = bundled_size.to_s image.add_element( bundled_size_element ) # ec2 encrypted key element. ec2_encrypted_key_element = REXML::Element.new( 'ec2_encrypted_key' ) ec2_encrypted_key_element.add_attribute( 'algorithm', cipher_algorithm ) ec2_encrypted_key_element.add_text( ec2_encrypted_key ) image.add_element( ec2_encrypted_key_element ) # user encrypted key element. user_encrypted_key_element = REXML::Element.new( 'user_encrypted_key' ) user_encrypted_key_element.add_attribute( 'algorithm', cipher_algorithm ) user_encrypted_key_element.add_text( user_encrypted_key ) image.add_element( user_encrypted_key_element ) # ec2 encrypted iv element. ec2_encrypted_iv_element = REXML::Element.new( 'ec2_encrypted_iv' ) ec2_encrypted_iv_element.add_text( ec2_encrypted_iv ) image.add_element( ec2_encrypted_iv_element ) # user encrypted iv element. user_encrypted_iv_element = REXML::Element.new( 'user_encrypted_iv' ) user_encrypted_iv_element.add_text( user_encrypted_iv ) image.add_element( user_encrypted_iv_element ) # parts - list of the image parts. parts_element = REXML::Element.new( 'parts' ) parts_element.add_attributes( {'count' => parts.size.to_s} ) index=0 parts.each do |part| # Add image part element for each image part. part_element = REXML::Element.new( 'part' ) part_element.add_attribute( 'index', index.to_s ) filename = REXML::Element.new( 'filename' ) filename.add_text( part[0] ) part_element.add_element( filename ) digest = REXML::Element.new( 'digest' ) digest.add_attribute( 'algorithm', digest_algorithm ) digest.add_text( Format::bin2hex( part[1] ) ) part_element.add_element( digest ) parts_element.add_element( part_element ) index+=1 end image.add_element( parts_element ) # Sign the manifest. sign( privkey_filename ) return true end |
#name ⇒ Object
189 190 191 |
# File 'lib/ec2/amitools/manifestv3.rb', line 189 def name() return get_element_text( 'image/name' ) end |
#parts ⇒ Object
A list of PartInformation instances representing the AMI parts.
240 241 242 243 244 245 246 247 248 249 |
# File 'lib/ec2/amitools/manifestv3.rb', line 240 def parts() parts = [] REXML::XPath.each( @doc.root,'image/parts/part' ) do |part| index = part.attribute( 'index' ).to_s.to_i filename = REXML::XPath.first( part, 'filename' ).text digest = Format::hex2bin( REXML::XPath.first( part, 'digest' ).text ) parts[index] = PartInformation.new( filename, digest ) end return parts end |
#sign(privkey_filename) ⇒ Object
Sign the manifest. If it is already signed, the signature and certificate will be replaced
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/ec2/amitools/manifestv3.rb', line 278 def sign( privkey_filename ) unless privkey_filename.kind_of? String and File::exist?( privkey_filename ) raise ArgumentError.new( "privkey_filename parameter invalid" ) end # Get the XML for image element and sign it. image_xml = XMLUtil.get_xml( @doc.to_s, 'image' ) sig = Crypto::sign( image_xml, privkey_filename ) # Create the signature and certificate elements. signature = REXML::Element.new( 'signature' ) signature.add_text( Format::bin2hex( sig ) ) @doc.root.delete_element( 'signature' ) @doc.root.add_element( signature ) end |
#signature ⇒ Object
Return the signature
295 296 297 |
# File 'lib/ec2/amitools/manifestv3.rb', line 295 def signature get_element_text('signature') end |
#size ⇒ Object
Return the size of the AMI.
252 253 254 |
# File 'lib/ec2/amitools/manifestv3.rb', line 252 def size() return get_element_text( 'image/size' ).to_i() end |
#to_s ⇒ Object
Return the manifest as an XML string.
307 308 309 |
# File 'lib/ec2/amitools/manifestv3.rb', line 307 def to_s() return @doc.to_s end |
#user ⇒ Object
311 312 313 |
# File 'lib/ec2/amitools/manifestv3.rb', line 311 def user() return get_element_text( 'image/user' ) end |
#user_encrypted_iv ⇒ Object
The user encrypted initialization vector hex encoded.
209 210 211 |
# File 'lib/ec2/amitools/manifestv3.rb', line 209 def user_encrypted_iv() return get_element_text( 'image/user_encrypted_iv' ) end |
#user_encrypted_key ⇒ Object
The user encrypted key hex encoded.
199 200 201 |
# File 'lib/ec2/amitools/manifestv3.rb', line 199 def user_encrypted_key() return get_element_text( 'image/user_encrypted_key' ) end |
#version ⇒ Object
315 316 317 |
# File 'lib/ec2/amitools/manifestv3.rb', line 315 def version() return get_element_text( 'version' ).to_i end |