...

Source file src/github.com/sassoftware/relic/lib/pkcs7/content.go

Documentation: github.com/sassoftware/relic/lib/pkcs7

     1  //
     2  // Copyright (c) SAS Institute Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package pkcs7
    18  
    19  import (
    20  	"encoding/asn1"
    21  )
    22  
    23  type contentInfo2 struct {
    24  	ContentType asn1.ObjectIdentifier
    25  	Value       asn1.RawValue
    26  }
    27  
    28  // Create a ContentInfo structure for the given bytes or structure. data can be
    29  // nil for detached signatures.
    30  func NewContentInfo(contentType asn1.ObjectIdentifier, data interface{}) (ci ContentInfo, err error) {
    31  	if data == nil {
    32  		return ContentInfo{ContentType: contentType}, nil
    33  	}
    34  	// There's no way to just encode the struct with the asn1.RawValue directly
    35  	// while also supporting the ability to not emit the 2nd field for the nil
    36  	// case, so instead this stupid dance of encoding it with the field then
    37  	// stuffing it into Raw is necessary...
    38  	encoded, err := asn1.Marshal(data)
    39  	if err != nil {
    40  		return ContentInfo{}, err
    41  	}
    42  	ci2 := contentInfo2{
    43  		ContentType: contentType,
    44  		Value: asn1.RawValue{
    45  			Class:      asn1.ClassContextSpecific,
    46  			Tag:        0,
    47  			IsCompound: true,
    48  			Bytes:      encoded,
    49  		},
    50  	}
    51  	ciblob, err := asn1.Marshal(ci2)
    52  	if err != nil {
    53  		return ContentInfo{}, nil
    54  	}
    55  	return ContentInfo{Raw: ciblob, ContentType: contentType}, nil
    56  }
    57  
    58  // Unmarshal a structure from a ContentInfo.
    59  func (ci ContentInfo) Unmarshal(dest interface{}) (err error) {
    60  	// First re-decode the contentinfo but this time with the second field
    61  	var ci2 contentInfo2
    62  	_, err = asn1.Unmarshal(ci.Raw, &ci2)
    63  	if err == nil {
    64  		// Now decode the raw value in the second field
    65  		_, err = asn1.Unmarshal(ci2.Value.Bytes, dest)
    66  	}
    67  	return
    68  }
    69  
    70  // Get raw content in DER encoding, or nil if it's not present
    71  func (ci ContentInfo) Bytes() ([]byte, error) {
    72  	var value asn1.RawValue
    73  	if err := ci.Unmarshal(&value); err != nil {
    74  		if _, ok := err.(asn1.SyntaxError); ok {
    75  			// short sequence because the value was omitted
    76  			return nil, nil
    77  		}
    78  		return nil, err
    79  	}
    80  	return value.Bytes, nil
    81  }
    82  

View as plain text