// Signs a block. The signing process takes the value of a block and signs // it using JWS. The signature generated is included in the // `signatures` block. If a block is empty or unknown, an error is returned. func (self *Stone) Sign(blockName string, privateKey string) (string, error) { var block map[string]interface{} signer, err := crypto.ParsePrivateKey([]byte(privateKey)) if err != nil { return "", errors.New("Private Key Error: " + err.Error()) } // block name must be known if !util.InStringSlice(KnownBlockNames, blockName) { return "", errors.New("block unknown") } block = self.getBlock(blockName) if util.IsMapEmpty(block) { return "", errors.New("failed to sign empty block") } // sign block payload, _ := util.MapToJSON(block) signature, err := signer.JWS_RSA_Sign(payload) if err != nil { return "", errors.New("failed to sign block") } self.Signatures[blockName] = signature return signature, nil }
// Validate a stone. func Validate(stoneData interface{}) error { var metaID string // parse stone data to map[string]interface{} stoneData is string var data map[string]interface{} switch d := stoneData.(type) { case string: decoder := json.NewDecoder(strings.NewReader(d)) decoder.UseNumber() if err := decoder.Decode(&data); err != nil { return errors.New("unable to parse json string") } break case map[string]interface{}: data = d break default: return errors.New("unsupported parameter type") } // must have `meta` block if data["meta"] == nil { return errors.New("missing `meta` block") } else { if !util.IsMapOfAny(data["meta"]) { return errors.New("`meta` block value type is invalid. Expects a JSON object") } if err := ValidateMetaBlock(data["meta"].(map[string]interface{})); err != nil { return err } metaBlock := data["meta"].(map[string]interface{}) metaID = metaBlock["id"].(string) } // if `ownership` block exists, it must be a map if data["ownership"] != nil { if !util.IsMapOfAny(data["ownership"]) { return errors.New("`ownership` block value type is invalid. Expects a JSON object") } if !util.IsMapEmpty(data["ownership"].(map[string]interface{})) { if err := ValidateOwnershipBlock(data["ownership"].(map[string]interface{}), metaID); err != nil { return err } } } // if `attributes` block exists, it must be a map if data["attributes"] != nil { if !util.IsMapOfAny(data["attributes"]) { return errors.New("`attributes` block value type is invalid. Expects a JSON object") } if !util.IsMapEmpty(data["attributes"].(map[string]interface{})) { if err := ValidateAttributesBlock(data["attributes"].(map[string]interface{}), metaID); err != nil { return err } } } // if `embeds` block exists, it must be a map if data["embeds"] != nil { if !util.IsMapOfAny(data["embeds"]) { return errors.New("`embeds` block value type is invalid. Expects a JSON object") } if !util.IsMapEmpty(data["embeds"].(map[string]interface{})) { if err := ValidateEmbedsBlock(data["embeds"].(map[string]interface{}), metaID); err != nil { return err } } } return nil }