// Contains determines if a key exists in the ring. The provided bytes should be the output of ssh.PublicKey.Marshal. func (b *boltKeyRing) Contains(key []byte) (exists bool) { b.users.WriteTx(func(bkt *bolt.Bucket) { // Get user bucket user := bkt.Bucket(b.username) // If user is nil, the user does not exist if user == nil { return } // Get keys sub-bucket keys, err := user.CreateBucketIfNotExists([]byte("keys")) if err != nil { return } // Create Fingerprint fingerprint := auth.CreateFingerprint(key) // Get fingerprint exists = keys.Get([]byte(fingerprint)) != nil return }) return }
// AddPublicKey simply adds a public key to the user's key ring func (b *boltKeyRing) AddPublicKey(pemBytes []byte) (fingerprint string, e error) { b.users.WriteTx(func(bkt *bolt.Bucket) { if len(pemBytes) == 0 { e = ErrInvalidCertificate return } // Get user bucket user := bkt.Bucket(b.username) // If user is nil, the user does not exist if user == nil { e = ErrUserDoesNotExist return } // Get keys sub-bucket keys, err := user.CreateBucketIfNotExists([]byte("keys")) if err != nil { return } // Decode PEM bytes block, _ := pem.Decode(pemBytes) if block == nil { e = ErrInvalidCertificate return } pub, err := x509.ParseCertificate(block.Bytes) if err != nil { e = ErrInvalidCertificate return } // Convert Public Key to SSH format sshKey, err := ssh.NewPublicKey(pub.PublicKey) if err != nil { e = ErrFailedKeyConvertion return } // Convert key to bytes key := sshKey.Marshal() fingerprint = auth.CreateFingerprint(key) // Write key to keys bucket e = keys.Put([]byte(fingerprint), key) return }) return }
func (suite *UserTestSuite) TestAddPublicKey() { name := "acme.user.add.key" // Create Certificate crt := suite.generateCertificate() // Create user user, err := suite.US.Create(name) suite.Nil(err) suite.NotNil(user) // Get key ring keyRing := user.KeyRing() suite.NotNil(keyRing) // Encode cert pemFile := new(bytes.Buffer) pemkey := &pem.Block{ Type: "CERTIFICATE", Bytes: crt} pem.Encode(pemFile, pemkey) // Add key fp, err := keyRing.AddPublicKey(pemFile.Bytes()) suite.Nil(err) // Validate key suite.KS.ReadTx(func(bkt *bolt.Bucket) { userBucket := bkt.Bucket([]byte(name)) keys := userBucket.Bucket([]byte("keys")) suite.NotNil(keys) // Pub key pub, err := x509.ParseCertificate(crt) suite.Nil(err) // Convert public key to SSH key format sshKey, err := ssh.NewPublicKey(pub.PublicKey) suite.Nil(err) // Convert key to bytes key := sshKey.Marshal() fingerprint := auth.CreateFingerprint(key) // Get key suite.Equal(key, keys.Get([]byte(fingerprint))) // Verify fingerprint suite.Equal(fingerprint, fp) }) }